情景cas server:cas 当用户在C1和C2都登录之后,获取到改用户在两个系统内各自需要的权限之后,在C1做登出操作,按照网上大部分的配置方法(web.xml中增加SingleSignOutFilter和SingleSignOutHttpSessionListener),可以在效果上看起来是登出了,但是并没有完全登出。 即: 原理分析1,2,3都很正常,问题出在第四步。 第四步仅仅是被SingleSignOutFilter拦截,根据service-ticket销毁掉改用户对应的session,而并没有调用shiro的subject.logout, 显然,subject.logout是做了销毁权限缓存等操作的 这样就会导致最终C2上的用户权限没有被清除,若在此时用户权限被修改,就会导致即使登出,C2上的权限也没有刷新 解决方案方案一权限缓存是可以设置过期时间的,那么简单点,只要给权限缓存加上过期时间即可,这样如果权限被修改,即使用户不登出,在过期之后,权限也会被刷新 方案二http://howiefh./2015/05/19/shiro-cas-single-sign-on/ 有一个很详细的说明,但是没仔细看,简单的说就是使用ServletContainerSessionManager,即shiro自己的session管理,似乎可以解决问题,但是未验证 方案三思路很简单,重写SingleSignOutFilter, 在登出的时候,调用subject.logout 即可。 奈何太年轻,这种方案有很多坑 坑一问题: Subject是由session中存放的一个key生成的,但是时序图中第四步是有cas发起的请求,而不是用户浏览器,即这个session中没有Subject信息,shiro无法获取到具体信息。 解决: 坑二问题: subject不提供设置principal接口,service-ticket session映射关系未提供get接口 解决: 坑三问题: SingleSignOutFilter是在ShiroFilter chain之前,也就是说,如果重写SingleSignOutFilter,在里边连一个不包含Principal的Subject都获取不到,但是如果把这个SimplePrincipalCollection放到 shrioFilter之后,登录的时候又会有问题 解决: shiro会针对配置的filter规则,取第一个匹配的作为最终的filter,而后边符合规则的就会被忽略掉 所以这里,要把SingleSignOutFilter和Shiro自己提供的CasFilter合并起来,放在一起作为一个filter 方案三代码经过这么一折腾,于是就有了下面的代码了
代码逻辑很简单,主要是要找到这么个解决方案,得一点点的调试和摸索,也是蛮有意思。
最后准备找个时间写个cas的faq,毕竟在开发过程中,遇到的很多常见问题,很是烦躁。 |
|