springboot前后端分离集成CAS单点登录(统一认证)
最近公司接了一个项目,甲方需要集成到金智系统登录,他们的数据在那边,然后需要使用cas来完成,网上了解了一下 大概就是通过cas系统来拦截请求验票,重定向到指定url登录以后再调回来处理请求接口
大致流程如下
1. 在Maven项目中引入CAS(Central Authentication Service)客户端核心库。CAS是一个开源的企业级单点登录解决方案,用于实现Web应用程序的集中认证和授权。
<dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.5.0</version> </dependency>
2.yml配置cas
3.cas配置类
@Configuration @Slf4j @ConditionalOnProperty(value = "cas.loginType", havingValue = "cas") public class CasFilterConfig { /** * 需要走cas拦截的地址(/* 所有地址都拦截) */ @Value("${cas.urlPattern:/*}") private String filterUrl; /** * 默认的cas地址,防止通过 配置信息获取不到 */ @Value("${cas.server-url-prefix}") private String casServerUrl; /** * 应用访问地址(这个地址需要在cas服务端进行配置) */ @Value("${cas.authentication-url}") private String authenticationUrl; /** * 应用访问地址(这个地址需要在cas服务端进行配置) */ @Value("${cas.client-host-url}") private String appServerUrl; @Bean public ServletListenerRegistrationBean servletListenerRegistrationBean() { log.info(" \n cas 单点登录配置 \n appServerUrl = " + appServerUrl + "\n casServerUrl = " + casServerUrl); log.info(" servletListenerRegistrationBean "); ServletListenerRegistrationBean listenerRegistrationBean = new ServletListenerRegistrationBean(); listenerRegistrationBean.setListener(new SingleSignOutHttpSessionListener()); listenerRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE); return listenerRegistrationBean; } /** * 单点登录退出 * * @return */ @Bean public FilterRegistrationBean singleSignOutFilter() { log.info(" servletListenerRegistrationBean "); FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new SingleSignOutFilter()); registrationBean.addUrlPatterns(filterUrl); registrationBean.addInitParameter("casServerUrlPrefix", casServerUrl); registrationBean.setName("CAS Single Sign Out Filter"); registrationBean.setOrder(1); return registrationBean; } /** * 单点登录认证 * * @return */ @Bean public FilterRegistrationBean AuthenticationFilter() { log.info(" AuthenticationFilter "); FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new AuthenticationFilter()); registrationBean.addUrlPatterns(filterUrl); registrationBean.setName("CAS Filter"); registrationBean.addInitParameter("casServerLoginUrl", casServerUrl); registrationBean.addInitParameter("serverName", appServerUrl); registrationBean.setOrder(1); return registrationBean; } /** * 单点登录校验 * * @return */ @Bean public FilterRegistrationBean Cas30ProxyReceivingTicketValidationFilter() { log.info(" Cas30ProxyReceivingTicketValidationFilter "); FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new Cas30ProxyReceivingTicketValidationFilter()); registrationBean.addUrlPatterns(filterUrl); registrationBean.setName("CAS Validation Filter"); registrationBean.addInitParameter("casServerUrlPrefix", authenticationUrl); registrationBean.addInitParameter("serverName", appServerUrl); registrationBean.setOrder(1); return registrationBean; } /** * 单点登录请求包装 * * @return */ @Bean public FilterRegistrationBean httpServletRequestWrapperFilter() { log.info(" httpServletRequestWrapperFilter "); FilterRegistrationBean registrationBean = new FilterRegistrationBean(); registrationBean.setFilter(new HttpServletRequestWrapperFilter()); registrationBean.addUrlPatterns(filterUrl); registrationBean.setName("CAS HttpServletRequest Wrapper Filter"); registrationBean.setOrder(1); return registrationBean; } }
4.对接cas统一认证后接受的用户信息对象
/** * @Author: * @Date: * @Description: 使用cas对接封装的cas返回的用户信息的对象 */ public class CasUtil { private static final Logger LOGGER = LoggerFactory.getLogger(CasUtil.class); /** * cas client 默认的session key */ public final static String CAS = "_const_cas_assertion_"; /** * 封装CasUserInfo * * @param request * @return */ public static CasUserInfo getCasUserInfoFromCas(HttpServletRequest request) { Object object = request.getSession().getAttribute(CAS); if (null == object) { return null; } Assertion assertion = (Assertion) object; return buildCasUserInfoByCas(assertion); } /** * 构建CasUserInfo * * @param assertion * @return */ private static CasUserInfo buildCasUserInfoByCas(Assertion assertion) { if (null == assertion) { LOGGER.error(" Cas没有获取到用户 "); return null; } CasUserInfo casUserInfo = new CasUserInfo(); String userName = assertion.getPrincipal().getName(); LOGGER.info(" cas对接登录用户= " + userName); casUserInfo.setUserAccount(userName); //获取属性值 Map<String, Object> attributes = assertion.getPrincipal().getAttributes(); Object name = attributes.get("cn"); casUserInfo.setUserName(name == null ? userName : name.toString()); casUserInfo.setAttributes(attributes); return casUserInfo; }
5.用户信息实体
/** * @Author: * @Date: * @Description: 返回的用户信息 */ @Setter @Getter public class CasUserInfo { /** 用户名 */ private String userName; /** 用户 */ private String userAccount; /** 用户信息 */ private Map<String, Object> attributes; }
6.验证统一认证登录后跳回来的处理
/** * 统一认证成功后跳转 * * @return */ @GetMapping(value = "/index") public ResponseVo<String> index(HttpServletRequest request) { CasUserInfo userInfo = CasUtil.getCasUserInfoFromCas(request); log.info("userInfo = " + JSONObject.toJSON(userInfo)); }
统一认证登录成功以后,回来再根据用户信息校验用户,生成对应token
7.退出
/** * 统一退出接口 * * @return */ @GetMapping(value = "/logout") public RedirectView logout(HttpServletRequest request) { // 清理缓存 // return "redirect:https://********/logout"; cas的退出 return new RedirectView("https://************/logout"); }
最后跳转回来的时候因为url里面带了;被拦截报错
The request was rejected because the URL contained a potentially malicious String ";"
最后在网上搜了一下相关错误
解决办法 在yml配置server加了以下配置
servlet: session: tracking-modes: cookie
到此这篇关于springboot前后端分离集成CAS单点登录(统一认证)的文章就介绍到这了,更多相关springboot CAS单点登录内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Windows系统下Eclipse搭建ESP32编译环境及安装过程
Ecppse 使用了 ESP-IDF 中的 Makefile 支持。这意味着您需要从创建 ESP-IDF 项目开始。您可以使用 github 中的 idf-template 项目,接下来通过本文给大家介绍Windows系统下Eclipse搭建ESP32编译环境及安装过程,感兴趣的朋友一起看看吧2021-10-10spring-data-elasticsearch @Field注解无效的完美解决方案
这篇文章主要介绍了spring-data-elasticsearch @Field注解无效的完美解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-07-07Mybatis传单个参数和<if>标签同时使用的问题及解决方法
这篇文章主要介绍了Mybatis传单个参数和<if>标签同时使用的问题及解决方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下2018-05-05
最新评论