首页 > 编程知识 正文

cas单点登录,CAS认证

时间:2023-05-04 14:39:46 阅读:31677 作者:3531

上一篇文章介绍了cas认证服务的整个过程。 本文的Springboot框架如何集成cas实现整个身份验证过程的方法;

1首先引入Springsecurity cas的依赖jar

compile ' org.spring framework.security 3360 spring-security-cas ' 2配置CasSecurityConfig类

@ configurationpublicclasscassecurityconfig { @ value (' $ { cas.server.URL } ) )专用字符串casserverurl; @value('${CAS.service.home} ) private String serverHome; @ value (' $ { cas.service.backendservice } ) private String backEndService; @value('${CAS.server.prefix} ) privatestringcasserverurlprefix; @ autowiredprivatecustomcasuserdetailsservicecustomcasuserdetailsservice; @ beanpublicservicepropertiesserviceproperties ((servicepropertiesserviceproperties=newserviceproperties ); 服务属性. setservice (backendservice '/log in/cas '; 服务属性. setsendrenew (false; 返回服务属性; } @ bean @ primarypublicauthenticationentrypointauthenticationentrypoint (servicepropertiessp ) casauthenticationentrypont/输入点. setserviceproperties (sp; 返回入口点; } @ beanpublicticketvalidatorticketvalidator () return cas 30 proxyticketvalidator ); } ticketvalidatorcas 30代理服务器(/是否打开代理cas 30 proxyticketvalidatorcas 30 proxyticketvalidator=newcas 30 proxyticketvalidator ) cas 30 proxyticketvalidator.setvalior cas 30 proxyticketvalidator.setacceptanyproxy (true; cas 30 proxyticketvalidator.seturlconnectionfactory (newsophonhttpsurlconnectionfactory () ); return cas 30代理服务器; } @ bean publiccasauthentication provider casauthentication provider ({ casauthentication provider=newcasauthentication provider ) 提供商. setticketvalidator (ticket validator ) ); 提供者. setauthenticationuserdetailsservice (customcasuserdetailsservice; provider.setkey (an _ id _ for _ this _ auth _ provider _ only ); 返回提供程序; } @ beanpublicsecuritycontextlogouthandlers

ecurityContextLogoutHandler() { return new SecurityContextLogoutHandler(); } @Bean public LogoutFilter logoutFilter() { //退出后转发路径 LogoutFilter logoutFilter = new LogoutFilter( casServerUrl + "/cas/logout?service=" + serverHome, securityContextLogoutHandler()); logoutFilter.setLogoutRequestMatcher(new AntPathRequestMatcher("/api/logout")); return logoutFilter; } @Bean public SingleSignOutFilter singleSignOutFilter() { //单点退出 SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter(); singleSignOutFilter.setCasServerUrlPrefix(casServerUrlPrefix); singleSignOutFilter.setIgnoreInitConfiguration(true); return singleSignOutFilter; } //设置退出监听 @EventListener public SingleSignOutHttpSessionListener singleSignOutHttpSessionListener( HttpSessionEvent event) { return new SingleSignOutHttpSessionListener(); }}

1)ServiceProperties配置了认证成功之后跳转的地址,cas在认证成功之后返回这个地址,并携带ticket;所以注意这个地址在springSecurity中一定是permitAll;不然会出现死循环;这里默认就使用这个地址"/login/cas",不然会有问题,后面会详细说;

2)AuthenticationEntryPoint配置了cas认证服务器的地址;

3)TicketValidator配置了校验ticket的类,应用接收到ticket之后,会通过这个类向cas认证服务器发送校验的请求校验ticket的有效性;

4)CasAuthenticationProvider 包含了校验ticket的配置以及校验成功之后获取用户信息的配置;这里配置的是CustomCasUserDetailsService

5)casServerUrlPrefix是cas的前缀地址,比如https://gg-sophon-13:8393/cas;

3>添加配置

在SecurityConfiguration中添加cas的过滤器,如图所示

同时添加如下配置bean

@Override protected AuthenticationManager authenticationManager(){ //设置cas认证提供 return new ProviderManager( Arrays.asList(authenticationProvider)); } @Bean public CasAuthenticationFilter casAuthenticationFilter(ServiceProperties sp) { //cas认证过滤器,当触发本filter时,对ticket进行认证 CasAuthenticationFilter filter = new CasAuthenticationFilter(); filter.setServiceProperties(sp); filter.setAuthenticationManager(authenticationManager()); filter.setAuthenticationSuccessHandler(new CasAuthenticationSuccessHandler()); return filter; }

整个配置到这里基本就结束了,下面跟踪下源码,解释下自己的两个疑问:

1.为什么serviceProperties.setService的地址后缀要是"/login/cas"?我改成其他的行不行,比如"/login/cas123"

2.具体校验ticket的逻辑是怎么处理的;

4>疑问解释

1)我把地址改成了"/login/cas123"

结果如图所示

那么为什么地址是"/login/cas"的时候就可以成功解析到ticket,然后去处理,改成"/login/cas123"就不行了那?带着疑问我断点调试了源代码发现

这里的返回值是ture,所以不需要认证,然后又没有一个接口或者页面对应就404了;跟踪进去这里的requiresAuthentication所做的操作

这里的match匹配的url是"/login/cas",而我们的request的地址是"/login/cas123",当然不匹配了;那么这个match中的地址是在哪里设置的那,我们看下AbstractAuthenticationProcessingFilter的子类CasAuthenticationFilter

在构造的时候默认这个地址就是"/login/cas";第一个问题解决了

2)第二个疑问,ticket拿到之后怎么处理的,这个是封装的,但是还是想看一下具体的逻辑;

跟踪到父类具体逻辑应该在这里

AbstractUrlBasedTicketValidator这个类里面

构造个ticket的url,根据cas的协议去校验,这个url地址是

https://gg-sophon-13:8393/cas/p3/proxyValidate?ticket=ST-218-ckNP-WOYieH2dg4dLZp2FUiw-xE-gg-sophon-13&service=http%3A%2F%2Flocalhost%3A8080%2Flogin%2Fcas

p3/proxyValidate 是api地址,应该是根据不同的cas协议,这个地址也是固定的,后面追加上ticket以及service地址;

验证完ticket之后,cas认证服务器返回用户的信息,以map的方式进行村粗;如图所示

然后调用我们之前定义的CustomCasUserDetailsService类loadUserDetails方法解析用户信息,之后存储在session中;

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。