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进行关系映射。

/**
* 安全管理中心。<br>
* 主要目的是保存session和ticket之间的关系。
* @author Weicl
* @since 2016.4.25
*/
public class CasSecurityManager extends DefaultWebSecurityManager{ Logger logger = LoggerFactory.getLogger(getClass()); @Override
protected void onSuccessfulLogin(AuthenticationToken token,
AuthenticationInfo info, Subject subject) { if (token instanceof CasToken) {
logger.info("save token info: " + token.getCredentials() + " -> " + subject.getSession(false).getId());
SsoUtils.putTokenCache((String)token.getCredentials(), subject.getSession(false).getId());
subject.getSession(false).setAttribute("_serviceTicket_", token.getCredentials());
} super.onSuccessfulLogin(token, info, subject);
}
}
PS: SsoUtils的putTokenCache。可以用ehcache或HashMap实现,其实没关系。

2 实现LogoutSloFilter

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

/**
* 单点登出处理
* @author Weicl
* @since 2016.4.25
*/
public class LogoutSloFilter extends AdviceFilter{
private final Logger logger = LoggerFactory.getLogger(getClass());
private final Pattern pattern = Pattern.compile("<samlp:SessionIndex>([^<]*)</samlp:SessionIndex>"); @Autowired
private NativeSessionManager nativeSessionManager; @Override
protected boolean preHandle(ServletRequest request, ServletResponse response)
throws Exception { try {
String logoutRequest = request.getParameter("logoutRequest");
String serviceTicket = extractServiceTicket(logoutRequest); logger.info(" slo serviceTicket : " + serviceTicket); String sessionId = (String)SsoUtils.getTokenCache(serviceTicket);
nativeSessionManager.stop(new DefaultSessionKey(sessionId)); } catch (Exception e) {
e.printStackTrace();
} response.getWriter().write("OK");
return false;
} /**
* 获取登出请求中的Ticket
* @param logoutRequest
* @return
*/
private String extractServiceTicket(String logoutRequest) {
Matcher matcher = pattern.matcher(logoutRequest);
if (matcher.find()) {
return matcher.group(1);
}
return "";
}
}

3 实现TicketSessionListener

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

/**
* 票据及session监听器
* @author Weicl
* @since 2016.4.25
*/
public class TicketSessionListener implements SessionListener{ Logger logger = LoggerFactory.getLogger(getClass()); @Override
public void onStart(Session session) { } @Override
public void onStop(Session session) {
logger.info("===============================");
logger.info("stop session:" + session.getId()); String ticket = (String)session.getAttribute("_serviceTicket_");
if (ticket != null) {
logger.info("remove serviceTicket: " + ticket);
SsoUtils.removeTokenCache(ticket);
}
} @Override
public void onExpiration(Session session) {
onStop(session);
}
}

4 配置到spring中

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

<!-- Shiro权限过滤过滤器定义 -->
<bean name="shiroFilterChainDefinitions" class="java.lang.String">
<constructor-arg>
<value>
/static/** = anon
/cas = cas
/login = authc
/logout = logout
/logoutSlo = logoutSlo
/** = user
</value>
</constructor-arg>
</bean> <!-- 安全认证过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="${cas.server.url}/login?service=${cas.project.url}${adminPath}/cas" />
<!--
<property name="loginUrl" value="${adminPath}/login" /> -->
<property name="successUrl" value="${adminPath}/login" />
<property name="filters">
<map>
<entry key="cas" value-ref="casFilter"/>
<entry key="authc" value-ref="formAuthenticationFilter"/>
<entry key="logout" value-ref="logoutFilter"></entry>
<entry key="logoutSlo" value-ref="logoutSloFilter"></entry>
</map>
</property>
<property name="filterChainDefinitions">
<ref bean="shiroFilterChainDefinitions"/>
</property>
</bean> <bean id="logoutSloFilter" class="cn.xxxxxx.base.modules.sys.security.LogoutSloFilter">
</bean> <!-- 定义Shiro安全管理配置 -->
<bean id="securityManager" class="cn.xxxxxx.base.common.security.shiro.session.CasSecurityManager">
<!-- <property name="realm" ref="systemAuthorizingRealm" /> -->
<property name="realm" ref="systemCasRealm" />
<property name="sessionManager" ref="sessionManager" />
<property name="cacheManager" ref="shiroCacheManager" />
</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. java生成二维码(需导入第三方ZXing.jar包)

    //这个类是用来解析,通过图片解析该图片的网页链接是什么 package util; import java.awt.Graphics2D;import java.awt.geom.AffineTra ...

  2. js高级编程中命名空间的两种用法

    第一种:// 声明一个全局对象Namespace,用来注册命名空间Namespace = new Object();// 全局对象仅仅存在register函数,参数为名称空间全路径,如"Gr ...

  3. sql server 中xml 数据类型的insert、update、delete

    近日对SQL操作XML作了如下整理: 1.插入 XML DECLARE @myDoc XMLSET @myDoc = '<Root> <ProductDescription Prod ...

  4. VTK的学习资源

    本文介绍从哪儿开始学习VTK(Visualization Toolkit的简称),如何在网上找寻VTK的学习资源. 首先,可以到维基百科或者百度百科上查看VTK条目,了解VTK是什么. http:// ...

  5. hping原理、安装、使用详解介绍

    [原理基础]  Hping是一个命令行下使用的TCP/IP数据包组装/分析工具,其命令模式很像Unix下的ping命令,但是它不是只能发送ICMP回应请求,它还可以支持TCP.UDP.ICMP和RAW ...

  6. Android常用库

    原文链接:http://www.jianshu.com/p/19368c2cdcaf 系统框架 1. 网络请求 Android Async HTTP Android异步HTTP库 AndroidAsy ...

  7. 0823--静默安装、fiddler设置断点、f12清除数据记录

    刚写了半天,然后没保存,哎,墙角抹泪. Anyway,记一下最近工作中遇到的问题吧. 1. 静默安装 cmd命令:拖入exe 文件,空格后输入--silent-install 若要在安装时修改主页,则 ...

  8. git提交远程仓库命令

    在已有的git库中搭建新库,并且将本地的git仓库,上传到远程服务器的git库中,从而开始一个新的项目 首先,在本地新建文件夹abc,进入到abc里面,然后git init.这样就在本地初始化了一个g ...

  9. 今天网站后台登录页面需要生成一个二维码,然后在手机app上扫描这个二维码,实现网站登录的效果及其解决方案如下

    要实现二维码登录,需要解决2个技术,1.需要js websocket 与后台php实现长连接技术 2.实现二维码生成技术 要实现这个功能第二个算是比较简单,只需要下载一个php的二维码生成器即可,但要 ...

  10. Linear Algebra lecture4 note

    Inverse of AB,A^(A的转置) Product of elimination matrices  A=LU (no row exchanges)   Inverse of AB,A^(A ...