希望长大对我而言,是可以做更多想做的事,而不是被迫做更多不想做的事...... 首页 CAS+Springboot单点登录 丁D 学无止境 2020-05-19 09:29 57183已阅读 CAS SSO 摘要本文将详细介绍CAS单点登录原理,服务端搭建,客户端搭建,返回多属性,自定义登陆页面,自定义登陆逻辑。 本文源码demo https://github.com/348786639/cas ### 什么是单点登录 单点登录就是登录一次处处已登录。 单点登录就是假设我有两个系统 比如 淘宝和天猫,我登录了淘宝,当我访问天猫的时候不用在登录一次。 ### CAS原理 ![](/upload/521643-20160308161733194-1732070037.gif) 文字描述 假设我们用3个系统 系统A,系统B,和认证中心 1、访问系统A,第一次访问没登陆,系统A重定向用户认证中心(带上service) 2、用户访问认证中心没有带上TGC(还没登陆),认证中心返回登陆页面 3、用户输入账号密码,进行登陆 4、认证中心进行登陆逻辑校验,成功就向客户端写cookie(TGC),并生成TGT缓存在服务器本地, 用TGT签发ST 5、用户认证中心重定向到第一次访问的带上的service(带上ST) 6、系统A的拦截器收到请求后,拿出ST,向认证中心询问ST是否有效(这个步骤对用户透明,直接使用http访问) 7、认证中心回复有效,并返回用户名字,和一些其他属性 8、系统A收到回复,建立本地Session 当用户第二次访问系统A的时候,由于第一次已经建立了本地session,所以成功登陆 1、当用户访问系统B的时候,没有本地session,系统B将请求重定向到用户认证中心(带上service) 2、这个时候用于我们第一次访问系统A的时候,用户认证中心,已经写下TGC,所以访问的是会带上TGC,认证中心根据TGC找到TGT,说明已经登陆过了 3、认证中心重定向到service地址带上ST 4、系统B收到ST向认证中心询问,ST是否有效,(这个步骤对用户透明,直接使用http访问) 5、认证中心回复有效,并返回用户名字,和一些其他属性 6、系统B收到回复,建立本地Session 参考 https://blog.csdn.net/ban_tang/article/details/80015946 https://www.cnblogs.com/notDog/p/5252973.html ### CAS Server搭建 1、从github下载解压(我选择5.2分支) https://github.com/apereo/cas-overlay-template 2、导入idea ![](/upload/微信图片_20200519112030.png) 目录结构如上图,我们自己建src/java/main、resource目录,并修改project structure ![](/upload/微信图片_20200519112239.png) ![](/upload/1589858647264_72031B3B-729C-4ae1-A463-B51FC902B608.png) 3、修改pom文件 由于我们使用overlay方式进行开发的,war引用的依赖我们在开发中是依赖不到的,所以我们如果使用到Cas的jar还是需要引用的,我们可以将生命周期设置为provided。 由于这里我要查询数据库和集成mybaits,所以也依赖了 ``` 4.0.0 org.apereo.cas cas-overlay war 1.0 org.apereo.cas cas-server-webapp${app.server} ${cas.version} war runtime org.apereo.cas cas-server-support-json-service-registry ${cas.version} provided org.apereo.cas cas-server-core-authentication ${cas.version} provided org.apereo.cas cas-server-core-authentication-api ${cas.version} provided mysql mysql-connector-java 5.1.44 org.mybatis mybatis-spring 2.0.3 org.mybatis mybatis 3.4.6 org.springframework.boot spring-boot-starter 1.5.2.RELEASE org.springframework.boot spring-boot-starter-logging org.apereo.cas cas-server-core-configuration ${cas.version} provided org.apereo.cas cas-server-support-rest ${cas.version} provided org.apereo.cas cas-server-core-webflow-api ${cas.version} provided org.apereo.cas cas-server-core-webflow ${cas.version} provided org.apereo.cas cas-server-support-actions ${cas.version} provided org.projectlombok lombok 1.12.6 provided com.rimerosolutions.maven.plugins wrapper-maven-plugin 0.0.4 true MD5 org.springframework.boot spring-boot-maven-plugin ${springboot.version} ${mainClassName} true ${isExecutable} WAR repackage org.apache.maven.plugins maven-war-plugin 2.6 cas false false false ${manifestFileToUse} org.apereo.cas cas-server-webapp${app.server} org.apache.maven.plugins maven-compiler-plugin 3.3 cas 5.2.6 1.5.12.RELEASE -tomcat org.springframework.boot.loader.WarLauncher false ${project.build.directory}/war/work/org.apereo.cas/cas-server-webapp${app.server}/META-INF/MANIFEST.MF 1.8 1.8 UTF-8 true default org.apereo.cas cas-server-webapp${app.server} ${cas.version} war runtime false exec org.apereo.cas.web.CasWebApplication true com.soebes.maven.plugins echo-maven-plugin 0.3.0 prepare-package echo Executable profile to make the generated CAS web application executable. false bootiful -tomcat false org.apereo.cas cas-server-webapp${app.server} ${cas.version} war runtime false pgp com.github.s4u.plugins pgpverify-maven-plugin 1.1.0 check hkp://pool.sks-keyservers.net ${settings.localRepository}/pgpkeys-cache test true false ``` 4、创建登陆处理类 这里我第一次先将账号密码写死,后面使用了jdbc去查询数据库,后面又集成了mybatis,所以这个比较乱,自行修改 ``` package com.ding; import org.apereo.cas.authentication.HandlerResult; import org.apereo.cas.authentication.PreventedException; import org.apereo.cas.authentication.UsernamePasswordCredential; import org.apereo.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler; import org.apereo.cas.authentication.principal.PrincipalFactory; import org.apereo.cas.services.ServicesManager; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import javax.security.auth.login.FailedLoginException; import java.security.GeneralSecurityException; import java.util.HashMap; import java.util.Map; /** * 自定义登陆逻辑参考和页面 * https://blog.csdn.net/u010588262/article/details/80014083 * https://blog.csdn.net/weixin_37548740/article/details/104053834 */ public class Login extends AbstractUsernamePasswordAuthenticationHandler { private SysUserMapper sysUserMapper; public Login(String name, ServicesManager servicesManager, PrincipalFactory principalFactory, Integer order,SysUserMapper sysUserMapper) { super(name, servicesManager, principalFactory, order); this.sysUserMapper = sysUserMapper; } @Override protected HandlerResult authenticateUsernamePasswordInternal(UsernamePasswordCredential usernamePasswordCredential, String s) throws GeneralSecurityException, PreventedException { //使用jdbc试一下 和使用mybatis试试 DriverManagerDataSource d=new DriverManagerDataSource(); d.setDriverClassName("com.mysql.jdbc.Driver"); d.setUrl("jdbc:mysql://127.0.0.1:3306/blog"); d.setUsername("root"); d.setPassword("123456"); JdbcTemplate template=new JdbcTemplate(); template.setDataSource(d); String username=usernamePasswordCredential.getUsername(); String pd=usernamePasswordCredential.getPassword(); Map user = template.queryForMap("SELECT `password` FROM t_sys_user WHERE user_name = ?", username); String pad = sysUserMapper.findUserName(username); System.out.printf(pad); //查询数据库加密的的密码 if(username==null || username.equals("admin1111")){ throw new FailedLoginException("没有该用户"); } //返回多属性 Map map=new HashMap<>(); map.put("email", "34865666@qq.com"); map.put("phone", "18850588888"); if(username.equals("admin") && pd.equals("123456")){ return createHandlerResult(usernamePasswordCredential, principalFactory.createPrincipal(username, map), null); } throw new FailedLoginException("Sorry, login attemp failed."); } } ``` 5、新增登陆配置器 ``` package com.ding; import org.apereo.cas.authentication.AuthenticationEventExecutionPlan; import org.apereo.cas.authentication.AuthenticationEventExecutionPlanConfigurer; import org.apereo.cas.authentication.AuthenticationHandler; import org.apereo.cas.authentication.principal.DefaultPrincipalFactory; import org.apereo.cas.configuration.CasConfigurationProperties; import org.apereo.cas.services.ServicesManager; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 還需要在下面这个问题配置 不然spring不会管理这个文件 * O:\cas\cas-overlay-template-5.2\cas-overlay-template-5.2\src\main\resource\META-INF\spring.factories */ @Configuration("CustomAuthConfig") @EnableConfigurationProperties(CasConfigurationProperties.class) public class CustomAuthConfig implements AuthenticationEventExecutionPlanConfigurer { @Autowired private CasConfigurationProperties casProperties; @Autowired @Qualifier("servicesManager") private ServicesManager servicesManager; @Autowired private SysUserMapper sysUserMapper; @Bean public AuthenticationHandler myAuthenticationHandler() { final Login handler = new Login(Login.class.getSimpleName(), servicesManager, new DefaultPrincipalFactory(), 10,sysUserMapper); return handler; } @Override public void configureAuthenticationExecutionPlan(AuthenticationEventExecutionPlan plan) { plan.registerAuthenticationHandler(myAuthenticationHandler()); } } ``` 还需要在src\main\resource\META-INF\spring.factories进行配置 这个文件我们可以去overlay复制过来修改 ``` org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.ding.CustomAuthConfig,\ com.ding.MyBatisDataSourceConfig ``` 6、resource建立services(注册客户端) 去将overlay的\services\HTTPSandIMAPS-10000001.json复制过来进行修改 这里由于我还没有配置https,先使用http所以serviceId配置http 我们可以通过这个进行自定义登陆页面 "theme": "blog",会找 resource\templates\blog\casLoginView.html ``` { "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^(https||http|imaps)://.*", "name" : "HTTPS and IMAPS", "id" : 10000001, "description" : "自定义登陆页面 theme 获取templates/blog/casLoginView.html", "evaluationOrder" : 10000, "theme": "blog", "attributeReleasePolicy": { "@class": "org.apereo.cas.services.ReturnAllAttributeReleasePolicy" } } ``` 7、配置application.properties配置文件 这个文件我们可以去overlay复制过来修改 ``` ## # CAS Server Context Configuration # server.context-path=/cas server.port=8080 #####start#########签发证书,如果是用spring boot之类嵌入式的容器,则需要改这里的配置,如果是直接部在tomcat中,则需要把tomcat改成https的################### #server.ssl.key-store=file:/etc/cas/thekeystore #server.ssl.key-store-password=changeit #server.ssl.key-password=changeit # server.ssl.ciphers= # server.ssl.client-auth= # server.ssl.enabled= # server.ssl.key-alias= # server.ssl.key-store-provider= # server.ssl.key-store-type= # server.ssl.protocol= # server.ssl.trust-store= # server.ssl.trust-store-password= # server.ssl.trust-store-provider= # server.ssl.trust-store-type= server.max-http-header-size=2097152 server.use-forward-headers=true server.connection-timeout=20000 server.error.include-stacktrace=ALWAYS server.compression.enabled=true server.compression.mime-types=application/javascript,application/json,application/xml,text/html,text/xml,text/plain server.tomcat.max-http-post-size=2097152 server.tomcat.basedir=build/tomcat server.tomcat.accesslog.enabled=true server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms) server.tomcat.accesslog.suffix=.log server.tomcat.max-threads=10 server.tomcat.port-header=X-Forwarded-Port server.tomcat.protocol-header=X-Forwarded-Proto server.tomcat.protocol-header-https-value=https server.tomcat.remote-ip-header=X-FORWARDED-FOR server.tomcat.uri-encoding=UTF-8 #####end#########签发证书,如果是用spring boot之类嵌入式的容器,则需要改这里的配置,如果是直接部在tomcat中,则需要把tomcat改成https的################### spring.http.encoding.charset=UTF-8 spring.http.encoding.enabled=true spring.http.encoding.force=true ## # CAS Cloud Bus Configuration # spring.cloud.bus.enabled=false # spring.cloud.bus.refresh.enabled=true # spring.cloud.bus.env.enabled=true # spring.cloud.bus.destination=CasCloudBus # spring.cloud.bus.ack.enabled=true endpoints.enabled=false endpoints.sensitive=true endpoints.restart.enabled=false endpoints.shutdown.enabled=false management.security.enabled=true management.security.roles=ACTUATOR,ADMIN management.security.sessions=if_required management.context-path=/status management.add-application-context-header=false security.basic.authorize-mode=role security.basic.enabled=false security.basic.path=/cas/status/** ## # CAS Web Application Session Configuration # server.session.timeout=300 server.session.cookie.http-only=true server.session.tracking-modes=COOKIE ## # CAS Thymeleaf View Configuration # spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.cache=true spring.thymeleaf.mode=HTML ## # CAS Log4j Configuration # # logging.config=file:/etc/cas/log4j2.xml server.context-parameters.isLog4jAutoInitializationDisabled=true ## # CAS AspectJ Configuration # spring.aop.auto=true spring.aop.proxy-target-class=true ## # CAS Authentication Credentials # #cas.authn.accept.users=casuser::Mellon #开启识别json文件,默认false #自动扫描服务配置,默认开启 #cas.serviceRegistry.watcherEnabled=true #120秒扫描一遍 #cas.serviceRegistry.repeatInterval=120000 #延迟15秒开启 #cas.serviceRegistry.startDelay=15000 #资源加载路径 cas.serviceRegistry.config.location=classpath:/services cas.tgc.secure=false cas.serviceRegistry.initFromJson=true # 默认主题 #cas.theme.defaultThemeName=blog ``` 8、自定义登陆页面 创建templates\blog目录及casLoginView.html文件 src\main\resource\templates\blog\casLoginView.html ``` 点我注册 ``` ### CAS Client搭建 1、新建一个spring boot项目 2、引入CAS客户端的依赖 ```yaml org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.2 org.springframework.boot spring-boot-starter-test test mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-thymeleaf org.jasig.cas.client cas-client-core 3.5.0 ``` 3、新增CAS客户端拦截器bean的配置 ``` package com.ding.cas; import org.jasig.cas.client.authentication.AuthenticationFilter; import org.jasig.cas.client.session.SingleSignOutFilter; import org.jasig.cas.client.session.SingleSignOutHttpSessionListener; import org.jasig.cas.client.util.AssertionThreadLocalFilter; import org.jasig.cas.client.util.HttpServletRequestWrapperFilter; import org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 查看下面这个链接和开放平台 * https://www.cnblogs.com/whm-blog/p/11248304.html */ @Configuration public class CasConfigure { @Autowired private CasClientProperties casClientProperties; /** * 用于实现单点登出功能 */ @Bean public ServletListenerRegistrationBean singleSignOutHttpSessionListener() { ServletListenerRegistrationBean listener = new ServletListenerRegistrationBean<>(); listener.setEnabled(true); listener.setListener(new SingleSignOutHttpSessionListener()); listener.setOrder(1); return listener; } /** * 该过滤器用于实现单点登出功能,单点退出配置,一定要放在其他filter之前 */ @Bean public FilterRegistrationBean singleSignOutFilter() { FilterRegistrationBean filterRegistration = new FilterRegistrationBean(); filterRegistration.setFilter(new SingleSignOutFilter()); filterRegistration.setEnabled(true); filterRegistration.addUrlPatterns(casClientProperties.getFilterUrl ()); filterRegistration.addInitParameter("casServerUrlPrefix", casClientProperties.getCasServerLoginUrl()); filterRegistration.addInitParameter("serverName", casClientProperties.getServerName()); filterRegistration.setOrder(3); return filterRegistration; } /** * 该过滤器负责用户的认证工作 * @return */ @Bean public FilterRegistrationBean authenticationFilterRegistrationBean() { FilterRegistrationBean authenticationFilter = new FilterRegistrationBean(); authenticationFilter.setFilter(new AuthenticationFilter()); Map initParameters = new HashMap<>(); initParameters.put("casServerLoginUrl", casClientProperties.getCasServerLoginUrl()); initParameters.put("ignorePattern", "/openApi/|/recall/|/test/|/health|/open/|/error*|/webjars/|/swagger*|/Mei*|/assets*|/v2/api*"); initParameters.put("serverName", casClientProperties.getServerName()); authenticationFilter.setInitParameters(initParameters); authenticationFilter.setOrder(4); List urlPatterns = new ArrayList<>(); urlPatterns.add(casClientProperties.getFilterUrl()); authenticationFilter.setUrlPatterns(urlPatterns); return authenticationFilter; } /** * 该过滤器负责对Ticket的校验工作 * @return */ @Bean public FilterRegistrationBean cas20ProxyReceivingTicketValidationFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new Cas30ProxyReceivingTicketValidationFilter()); registrationBean.addUrlPatterns("/*"); registrationBean.addInitParameter("casServerUrlPrefix", casClientProperties.getCasServerUrlPrefix()); registrationBean.addInitParameter("serverName", casClientProperties.getServerName()); registrationBean.addInitParameter("useSession", String.valueOf(true)); registrationBean.addInitParameter("exceptionOnValidationFailure", String.valueOf(false)); registrationBean.addInitParameter("redirectAfterValidation", String.valueOf(true)); registrationBean.setEnabled(casClientProperties.isEnable()); registrationBean.setOrder(4); return registrationBean; } /** * 该过滤器对HttpServletRequest请求包装, 可通过HttpServletRequest的getRemoteUser()方法获得登录用户的登录名 * @return */ @Bean public FilterRegistrationBean casHttpServletRequestWrapperFilter(){ FilterRegistrationBean authenticationFilter = new FilterRegistrationBean(); authenticationFilter.setFilter(new HttpServletRequestWrapperFilter()); authenticationFilter.setOrder(6); List urlPatterns = new ArrayList(); urlPatterns.add(casClientProperties.getFilterUrl()); authenticationFilter.setUrlPatterns(urlPatterns); return authenticationFilter; } /** * 该过滤器使得可以通过org.jasig.cas.client.util.AssertionHolder来获取用户的登录名。 * 比如AssertionHolder.getAssertion().getPrincipal().getName()。 * 这个类把Assertion信息放在ThreadLocal变量中,这样应用程序不在web层也能够获取到当前登录信息 * @return */ @Bean public FilterRegistrationBean casAssertionThreadLocalFilter(){ FilterRegistrationBean authenticationFilter = new FilterRegistrationBean(); authenticationFilter.setFilter(new AssertionThreadLocalFilter()); authenticationFilter.setOrder(7); List urlPatterns = new ArrayList(); urlPatterns.add(casClientProperties.getFilterUrl()); authenticationFilter.setUrlPatterns(urlPatterns); return authenticationFilter; } } ``` ``` @Configuration public class CasClientProperties { /** * 是否开启单点登录 */ private boolean enable = true; /** * 单点登录需要访问的CAS SERVER URL入口 */ private String casServerLoginUrl; /** * 托管此应用的服务器名称,例如本机:http://localhost:8080 */ private String serverName; /** * cas服务器的开头 例如 http://localhost:8443/cas */ private String casServerUrlPrefix; /** * 验证白名单,当请求路径匹配此表达式时,自动通过验证 */ private String ignorePattern; /** * 白名单表达式的类型 * REGEX 正则表达式 默认的 * CONTAINS 包含匹配 * EXACT 精确匹配 */ private String ignoreUrlPatternType; private String filterUrl; setget方法 } ``` 4、新增登陆成功页面 ``` @Controller public class IndexController { @RequestMapping("/index") public String sayHello(){ //方案一:获取其他属性和名字 Map map = AssertionHolder.getAssertion().getPrincipal().getAttributes(); AssertionHolder.getAssertion().getPrincipal().getName(); //方案二:获取其他属性和名字 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); Principal principal = request.getUserPrincipal(); Map attributes = ((AttributePrincipal) principal).getAttributes(); return "index"; } /** * 验证会不会被拦截 * @return */ @RequestMapping("/openApi/openApi") public String openApi(){ return "openApi"; } } ``` 新增index.html页面和openApi.html ``` Title index ``` ### CAS 安全性 #### TGC的安全性 对于一个CAS用户来说,最重要是要保护它的 TGC ,如果 TGC 不慎被 CAS Server 以外的实体获得, Hacker 能够找到该 TGC ,然后冒充 CAS 用户访问所有授权资源。 从基础模式可以看出, TGC 是 CAS Server 通过 SSL 方式发送给终端用户,因此,要截取 TGC 难度非常大,从而确保 CAS 的安全性。所以CAS的安全性是依赖于SSL的。 TGC 面临的风险主要并非传输窃取。比如你登陆了之后,没有 Logout ,离开了电脑,别人就可以打开你的浏览器,直接访问你授权访问的应用 ,设置一个 TGC 的有效期,可以减少被别人盗用 #### Service Ticket安全性 首要明白, Service Ticket 是通过 Http 传送的,所有网络中的其他人可以 Sniffer 到其他人的 Ticket 。 CAS 协议从几个方面让 Service Ticket 变得更加安全。 1、Service Ticket 只能使用一次。 CAS 协议规定,无论 Service Ticket 验证是否成功, CAS Server 都会将服务端的缓存中清除该 Ticket ,从而可以确保一个 Service Ticket 不能被使用两次。 2、Service Ticket 在一段时间内失效。 假设用户拿到 Service Ticket 之后,他请求 helloservice 的过程又被中断了, Service Ticket 就被空置了,事实上,此时, Service Ticket 仍然有效。 CAS 规定 Service Ticket 只能存活一定的时间,然后 CAS Server 会让它失效。 ### url带jsessionid处理 如下面链接,当我们从cas登录成功后跳回页面,url后面带上jsessionid,这样看起来很别扭 http://127.0.0.1:10086/index;jsessionid=5D9A11B35C145518155D141B771368F0 去掉jsessionid方法 我们只需要在cas登录页面form表单提交的时候设置**method="POST"**,post要大写,小写不行 ```yaml ``` ### CAS返回多属性 默认情况下CAS只会返回username给客户端,但是在实际情况下,一个username是不能满足我们的要求的,我们可能需要邮件,电话号码,权限等数据,所以我们需要对CAS进行改造 1、修改Cas server的services文件 ``` 修改services可以设置不同的客户端返回不同的属性 使用ReturnAllAttributeReleasePolicy表示返回所有的属性,当然也可以限制返回部分属性,限制哪些属性不能返回。 { "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^(https||http|imaps)://.*", "name" : "HTTPS and IMAPS", "id" : 10000001, "description" : "自定义登陆页面 theme 获取templates/blog/casLoginView.html", "evaluationOrder" : 10000, "theme": "blog", "attributeReleasePolicy": { "@class": "org.apereo.cas.services.ReturnAllAttributeReleasePolicy" } } ``` 2、在CAS server修改登陆处理逻辑 ``` 。。。。 。。。。 //返回多属性 Map map=new HashMap<>(); map.put("email", "34865666@qq.com"); map.put("phone", "18850588888"); if(username.equals("admin") && pd.equals("123456")){ return createHandlerResult(usernamePasswordCredential, principalFactory.createPrincipal(username, map), null); } throw new FailedLoginException("Sorry, login attemp failed."); ``` 3、修改客户端 原本我以为只要执行上面2个步骤就行了。但是实际上,我在客户端还是获取不到。 这里我的CAS是5.2.26版本,原本是使用CAS2.0协议的,需要改成CAS3.0协议, 我们需要在检查Ticket的时候使用Cas30ProxyReceivingTicketValidationFilter,原本是使用Cas20ProxyReceivingTicketValidationFilter不行 ``` /** * 该过滤器负责对Ticket的校验工作 * @return */ @Bean public FilterRegistrationBean cas20ProxyReceivingTicketValidationFilter() { FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new Cas30ProxyReceivingTicketValidationFilter()); registrationBean.addUrlPatterns("/*"); registrationBean.addInitParameter("casServerUrlPrefix", casClientProperties.getCasServerUrlPrefix()); registrationBean.addInitParameter("serverName", casClientProperties.getServerName()); registrationBean.addInitParameter("useSession", String.valueOf(true)); registrationBean.addInitParameter("exceptionOnValidationFailure", String.valueOf(false)); registrationBean.addInitParameter("redirectAfterValidation", String.valueOf(true)); registrationBean.setEnabled(casClientProperties.isEnable()); registrationBean.setOrder(4); return registrationBean; ``` 4.客戶端获取数据 ``` @RequestMapping("/index") public String sayHello(){ //方案一:获取其他属性和名字 Map map = AssertionHolder.getAssertion().getPrincipal().getAttributes(); AssertionHolder.getAssertion().getPrincipal().getName(); //方案二:获取其他属性和名字 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); Principal principal = request.getUserPrincipal(); Map attributes = ((AttributePrincipal) principal).getAttributes(); return "index"; } ``` 参考 * https://blog.csdn.net/u010588262/article/details/80014083 * https://blog.csdn.net/weixin_37548740/article/details/104053834 很赞哦! (2) 上一篇:spring cloud注册中心之Eureka 下一篇:Elasticsearch索引管理 目录 点击排行 Elasticsearch6.3.2之x-pack redis哨兵 2019-07-09 22:05 Redis+Twemproxy+HAProxy+Keepalived 2019-07-12 17:20 GC优化策略和相关实践案例 2019-10-10 10:54 JVM垃圾回收器 2019-10-10 10:23 标签云 Java Spring MVC Mybatis Ansible Elasticsearch Redis Hive Docker Kubernetes RocketMQ Jenkins Nginx 友情链接 郑晓博客 佛布朗斯基 凉风有信 MarkHoo's Blog 冰洛博客 南实博客 Rui | 丁D Java研发工程师 生活可以用「没办法」三个字概括。但别人的没办法是「腿长,没办法」、「长得好看,没办法」、「有才华,没办法」。而你的没办法,是真的没办法。 请作者喝咖啡