spring - Spring Security + CAS + Tomcat:不监听url:/login/cas
问题描述
我正在学习 Spring 安全性。我开发了一个通过 CAS 进行身份验证的应用程序。我从本教程的示例开始:https ://www.baeldung.com/spring-security-cas-sso 。
WebSecurityConfig文件的内容是:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class);
private SingleSignOutFilter singleSignOutFilter;
private LogoutFilter logoutFilter;
private CasAuthenticationProvider casAuthenticationProvider;
private ServiceProperties serviceProperties;
@Autowired
public WebSecurityConfig(SingleSignOutFilter singleSignOutFilter, LogoutFilter logoutFilter,
CasAuthenticationProvider casAuthenticationProvider,
ServiceProperties serviceProperties) {
this.logoutFilter = logoutFilter;
this.singleSignOutFilter = singleSignOutFilter;
this.serviceProperties = serviceProperties;
this.casAuthenticationProvider = casAuthenticationProvider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers( "/secured", "/login").authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint())
.and()
.addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class)
.addFilterBefore(logoutFilter, LogoutFilter.class)
.csrf().ignoringAntMatchers("/exit/cas");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(casAuthenticationProvider);
}
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return new ProviderManager(Collections.singletonList(casAuthenticationProvider));
}
public AuthenticationEntryPoint authenticationEntryPoint() {
CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
entryPoint.setLoginUrl("http://cas-docker:7080/cas/login");
entryPoint.setServiceProperties(serviceProperties);
return entryPoint;
}
}
Spring应用文件的内容是:
@SpringBootApplication
public class CasSecuredApplication extends SpringBootServletInitializer {
private static final Logger logger = LoggerFactory.getLogger(CasSecuredApplication.class);
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(CasSecuredApplication.class);
}
public static void main(String... args) {
SpringApplication.run(CasSecuredApplication.class, args);
}
@Bean
public CasAuthenticationFilter casAuthenticationFilter(
AuthenticationManager authenticationManager,
ServiceProperties serviceProperties) throws Exception {
CasAuthenticationFilter filter = new CasAuthenticationFilter();
filter.setAuthenticationManager(authenticationManager);
filter.setServiceProperties(serviceProperties);
return filter;
}
@Bean
public ServiceProperties serviceProperties() {
logger.info("service properties");
ServiceProperties serviceProperties = new ServiceProperties();
serviceProperties.setService("https://tomcat-docker:8443/cas-secured-app-0.0.1-SNAPSHOT/login/cas");
serviceProperties.setSendRenew(false);
return serviceProperties;
}
@Bean
public TicketValidator ticketValidator() {
return new Cas30ServiceTicketValidator("http://cas-docker:7080/cas");
}
@Bean
public CasAuthenticationProvider casAuthenticationProvider(
TicketValidator ticketValidator,
ServiceProperties serviceProperties) {
CasAuthenticationProvider provider = new CasAuthenticationProvider();
provider.setServiceProperties(serviceProperties);
provider.setTicketValidator(ticketValidator);
provider.setUserDetailsService(
s -> new User("test@test.com", "Mellon", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_ADMIN")));
provider.setKey("CAS_PROVIDER_LOCALHOST_8900");
return provider;
}
@Bean
public SecurityContextLogoutHandler securityContextLogoutHandler() {
return new SecurityContextLogoutHandler();
}
@Bean
public LogoutFilter logoutFilter() {
LogoutFilter logoutFilter = new LogoutFilter("https://tomcat-docker:8443/logout", securityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl("/logout/cas");
return logoutFilter;
}
@Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
singleSignOutFilter.setLogoutCallbackPath("/exit/cas");
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
}
}
当我访问/login时,会重定向到 CAS 保护区。然后,显示登录屏幕,我输入名称和密码,然后单击登录会话按钮。之后,CAS 重定向到这个 url:
https://tomcat-docker:8443/cas-secured-app-0.0.1-SNAPSHOT/login/cas?ticket=ST-10-23dDew2ztSMwkbEXgtDC-9086a9962d01
在此之后,得到以下错误:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri May 21 10:24:12 UTC 2021
There was an unexpected error (type=Internal Server Error, status=500).
此链接https://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/cas.html提到过滤器始终在侦听对/login/cas的请求。
为什么过滤器不侦听 /login/cas 并继续进行身份验证过程?代码中是否缺少某些内容?
更新:
CAS 服务器日志显示以下内容:
2021-05-21 12:43:56,544 INFO [org.apereo.inspektr.audit.support.Slf4jLoggingAuditTrailManager] - <Audit trail record BEGIN
=============================================================
WHO: casuser
WHAT: ST-18-snPFz6n5AdakHvBpROlf-9086a9962d01 for https://localhost:8443/login/cas
ACTION: SERVICE_TICKET_CREATED
APPLICATION: CAS
WHEN: Fri May 21 12:43:56 UTC 2021
CLIENT IP ADDRESS: 172.19.0.1
SERVER IP ADDRESS: 172.19.0.6
=============================================================
在属性文件中,我放了:
server.servlet.contextPath=/cas-secured-app-0.0.1-SNAPSHOT
CAS 服务器配置是默认的。我没有碰过它。
为什么 Cas 服务器说它正在监听https://localhost:8443/login/cas?是否需要配置 CAS 服务器?
解决方案
推荐阅读
- ios - 此视频中的 IOS 动画
- php - 如何将 rand() 值存储在会话变量中而不在下次执行时覆盖它
- c# - 所有在方法上创建的变量都被销毁然后程序完成了吗?
- r - 何时使用训练验证测试集
- mysql - 日志文件中的“数据字典升级”后 MySQL 8 不会启动
- ruby-on-rails - 如何在多个 EC2 实例上同时部署一个应用程序?
- c# - 动态查询通用仓库中的表
- android - 带有后延迟的单元测试方法
- reactjs - React Hook "useState" 在函数 "app" 中被调用,它既不是 React 函数组件也不是自定义 React Hook 函数
- reactjs - 如何修复 create-react-app 不加载 CSS 模块?