1 Single Sign Out 功能

即单点登出功能。也就是在任意子系统进行登出操作后,其他子系统会自动登出。

实际CAS登出的步骤为

所以每个子系统都需要实现一个sso登出响应。

cas-client-core包中有Single Sign Out的Session容器实现。

具体在包 org.jasig.cas.client.session 中。

2 实现Shiro的SSO登出功能

1 实现CasSecurityManager

主要目的是为了在登陆成功后保存 ST票据,并与 Shiro的sessionId进行关系映射。

  1. /**
  2. * 安全管理中心。<br>
  3. * 主要目的是保存session和ticket之间的关系。
  4. * @author Weicl
  5. * @since 2016.4.25
  6. */
  7. public class CasSecurityManager extends DefaultWebSecurityManager{
  8.  
  9. Logger logger = LoggerFactory.getLogger(getClass());
  10.  
  11. @Override
  12. protected void onSuccessfulLogin(AuthenticationToken token,
  13. AuthenticationInfo info, Subject subject) {
  14.  
  15. if (token instanceof CasToken) {
  16. logger.info("save token info: " + token.getCredentials() + " -> " + subject.getSession(false).getId());
  17. SsoUtils.putTokenCache((String)token.getCredentials(), subject.getSession(false).getId());
  18. subject.getSession(false).setAttribute("_serviceTicket_", token.getCredentials());
  19. }
  20.  
  21. super.onSuccessfulLogin(token, info, subject);
  22. }
  23. }
  1. PS: SsoUtilsputTokenCache。可以用ehcacheHashMap实现,其实没关系。

2 实现LogoutSloFilter

这个拦截器用来处理sso登出请求。

  1. /**
  2. * 单点登出处理
  3. * @author Weicl
  4. * @since 2016.4.25
  5. */
  6. public class LogoutSloFilter extends AdviceFilter{
  7. private final Logger logger = LoggerFactory.getLogger(getClass());
  8. private final Pattern pattern = Pattern.compile("<samlp:SessionIndex>([^<]*)</samlp:SessionIndex>");
  9.  
  10. @Autowired
  11. private NativeSessionManager nativeSessionManager;
  12.  
  13. @Override
  14. protected boolean preHandle(ServletRequest request, ServletResponse response)
  15. throws Exception {
  16.  
  17. try {
  18. String logoutRequest = request.getParameter("logoutRequest");
  19. String serviceTicket = extractServiceTicket(logoutRequest);
  20.  
  21. logger.info(" slo serviceTicket : " + serviceTicket);
  22.  
  23. String sessionId = (String)SsoUtils.getTokenCache(serviceTicket);
  24. nativeSessionManager.stop(new DefaultSessionKey(sessionId));
  25.  
  26. } catch (Exception e) {
  27. e.printStackTrace();
  28. }
  29.  
  30. response.getWriter().write("OK");
  31. return false;
  32. }
  33.  
  34. /**
  35. * 获取登出请求中的Ticket
  36. * @param logoutRequest
  37. * @return
  38. */
  39. private String extractServiceTicket(String logoutRequest) {
  40. Matcher matcher = pattern.matcher(logoutRequest);
  41. if (matcher.find()) {
  42. return matcher.group(1);
  43. }
  44. return "";
  45. }
  46. }

3 实现TicketSessionListener

这个类的作用是当session终止的时候,释放 SsoUtil 中的tokenCache。因为应用的session不存在了,保存这个映射关系也没有意义,而且浪费缓存空间。

  1. /**
  2. * 票据及session监听器
  3. * @author Weicl
  4. * @since 2016.4.25
  5. */
  6. public class TicketSessionListener implements SessionListener{
  7.  
  8. Logger logger = LoggerFactory.getLogger(getClass());
  9.  
  10. @Override
  11. public void onStart(Session session) {
  12.  
  13. }
  14.  
  15. @Override
  16. public void onStop(Session session) {
  17. logger.info("===============================");
  18. logger.info("stop session:" + session.getId());
  19.  
  20. String ticket = (String)session.getAttribute("_serviceTicket_");
  21. if (ticket != null) {
  22. logger.info("remove serviceTicket: " + ticket);
  23. SsoUtils.removeTokenCache(ticket);
  24. }
  25. }
  26.  
  27. @Override
  28. public void onExpiration(Session session) {
  29. onStop(session);
  30. }
  31. }

4 配置到spring中

一下为添加/修正的关键代码。其他shiro的配置这边就不贴出来了。

  1. <!-- Shiro权限过滤过滤器定义 -->
  2. <bean name="shiroFilterChainDefinitions" class="java.lang.String">
  3. <constructor-arg>
  4. <value>
  5. /static/** = anon
  6. /cas = cas
  7. /login = authc
  8. /logout = logout
  9. /logoutSlo = logoutSlo
  10. /** = user
  11. </value>
  12. </constructor-arg>
  13. </bean>
  14.  
  15. <!-- 安全认证过滤器 -->
  16. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  17. <property name="securityManager" ref="securityManager" />
  18. <property name="loginUrl" value="${cas.server.url}/login?service=${cas.project.url}${adminPath}/cas" />
  19. <!--
  20. <property name="loginUrl" value="${adminPath}/login" /> -->
  21. <property name="successUrl" value="${adminPath}/login" />
  22. <property name="filters">
  23. <map>
  24. <entry key="cas" value-ref="casFilter"/>
  25. <entry key="authc" value-ref="formAuthenticationFilter"/>
  26. <entry key="logout" value-ref="logoutFilter"></entry>
  27. <entry key="logoutSlo" value-ref="logoutSloFilter"></entry>
  28. </map>
  29. </property>
  30. <property name="filterChainDefinitions">
  31. <ref bean="shiroFilterChainDefinitions"/>
  32. </property>
  33. </bean>
  34.  
  35. <bean id="logoutSloFilter" class="cn.xxxxxx.base.modules.sys.security.LogoutSloFilter">
  36. </bean>
  37.  
  38. <!-- 定义Shiro安全管理配置 -->
  39. <bean id="securityManager" class="cn.xxxxxx.base.common.security.shiro.session.CasSecurityManager">
  40. <!-- <property name="realm" ref="systemAuthorizingRealm" /> -->
  41. <property name="realm" ref="systemCasRealm" />
  42. <property name="sessionManager" ref="sessionManager" />
  43. <property name="cacheManager" ref="shiroCacheManager" />
  44. </bean>

在shiro-cas中实现 Jasig-cas的Single Sign Out 功能的更多相关文章

  1. 源代码解读Cas实现单点登出(single sign out)功能实现原理

    关于Cas实现单点登入(single sing on)功能的文章在网上介绍的比较多,想必大家多多少少都已经有所了解,在此就不再做具体介绍.如果不清楚的,那只能等我把single sign on这块整理 ...

  2. 源代码解读Cas实现单点登出(single sign out)功能实现原理--转

    关于Cas实现单点登入(single sing on)功能的文章在网上介绍的比较多,想必大家多多少少都已经有所了解,在此就不再做具体介绍.如果不清楚的,那只能等我把single sign on这块整理 ...

  3. Laravel5中集成Jasig cas统一认证系统

    CAS : CAS(Central Authentication Service)是一款不错的针对 Web 应用的单点登录框架,这里介绍下我刚在laravel5上搭建成功的cas.提前准备工作:可运行 ...

  4. cas错误:org.jasig.cas.client.validation.TicketValidationException: No principal was found in the response from the CAS server.

    这个问题困扰了我好几天,最终被这个哥们解决了,具体请参考:http://www.oschina.net/question/252484_149958?sort=time

  5. 单点登录(四)-----遇到问题-----cas server 源码部署tomcat运行报错ClassNotFoundException: org.jasig.cas.CasEnvironmentCo

    情况 cas单点登录 cas server 源码部署tomcat运行报错 把cas server的代码下载下来后使用gradle插件或者maven插件以及转化成eclipse·后导入发现部署到tomc ...

  6. jasig CAS 实现单点登录 - java、php客户端登录实现

    jasig CAS项目本身就是一个完整的CAS单点登录服务 1.服务端需要把  认证处理类.用户属性返回值处理类 调整成我们自己处理类即可实现单点登录 2.java客户端需要引入cas-client- ...

  7. cas 单点登录出现org.jasig.cas.client.util.CommonUtils.getResponseFromServer - 拒绝连接 Connection refused

    cas 单点登录出现org.jasig.cas.client.util.CommonUtils.getResponseFromServer - 拒绝连接 Connection refused 环境: ...

  8. Configuring the JA-SIG CAS Client --官方

    1. for Java using Spring Configuration of the CAS Client for Java via Spring IoC will depend heavily ...

  9. CAS中的ABA问题

    http://coolshell.cn/articles/8239.html CAS的ABA问题 所谓ABA(见维基百科的ABA词条),问题基本是这个样子: 进程P1在共享变量中读到值为A P1被抢占 ...

随机推荐

  1. CPU指令集

    cpu作为一台电脑中的核心,它的作用是无法替代的.而cpu本身只是在块硅晶片上所集成的超大规模的集成电路,集成的晶体管数量可达到上亿个,是由非常先进复杂的制造工艺制造出来的,拥有相当高的科技含量. C ...

  2. ARM指令教程

    ARM指令教程 ARM汇编程序特点: l         所有运算处理都是发生通用寄存器(一般是R0~R14)的之中.所有存储器空间(如C语言变量的本质就是一个存储器空间上的几个BYTE).的值的处理 ...

  3. C语言文件处理

    数据存储方式: 数据->变量->文件 数据 10个学生的信息: #define N 10 struct student { char stu_num[15]; char stu_name[ ...

  4. Sep14学习笔记_pipe() & fork()

    第一次用博客园,昨晚编辑器一直没打开,今天打开了,把昨天的内容先补一下 关于parent和child之间的数据传输: If the parent wants to receive data from ...

  5. iOS 动态下载系统提供的中文字体

    使用系统提供的中文字体,既可避免版权问题,又可以减小应用体积 #pragma mark - 判断字体是否已经被下载 - (BOOL)isFontDownLoaded:(NSString *)fontN ...

  6. servlet/jsp详解

    首先谈servlet的简单定义,servlet其实就是一门web服务器端编程的技术. servlet它分两种,一种是servlet容器,所有的servlet对象都要放在servlet容器中才能被调用执 ...

  7. JS实现HashMap

    /** * ********* 操作实例 ************** * var map = new HashMap(); * map.put("key1","Valu ...

  8. jQuery中的map()方法

    jQuery中map()方法的使用格式为:$(selector).map(callback(index,domElement)). 将在每一个被选元素上执行map()方法中设置的回调函数,在回调函数中 ...

  9. 基于jQuery的email suggest插件

    最近项目中有表单提交的地方需要用户填写邮箱,PM(产品经理)和运营都强烈要求在用户填写邮箱的时候出现suggest列表,简化用户输入的填写流程.我考虑了下,这个应该也是经常会用到的功能,细心的朋友可能 ...

  10. 使用subclass UIActivity的方案来分享图片

    IOS6开始, 系统提供了UIActivityViewController, 对图片,文字,url进行相关的操作. 对于缺乏UI设计师的开发来说, 使用它进行轻量级的分享是很好的选择. 最大的缺点是自 ...