CAS的登录和注销原理

【原创申明:文章为原创,欢迎非盈利性转载,但转载必须注明来源】

之前写过一篇文章,介绍单点登录的基本原理。这篇文章重点介绍开源单点登录系统CAS的登录和注销的实现方法。并结合实际工作中碰到的问题,探讨在集群环境中应用单点登录可能会面临的问题。

1      单点登录的过程

为了描述方便,假设有如下一个单点登录系统。一套CASServer,两套CAS Client系统。为了描述的方便,省略CAS Server调用用户系统完成登录,以及CASClient从用户系统读取用户详细信息的过程。

1.1多应用情况下Session信息

假定有两个CAS Client应用,一个CAS Server。应用的部署,可能在不同的服务器,也可能有不同的访问IP或域名,即使是同一个浏览器,在各个应用中的Session信息也是不相同的。

浏览器中,每个应用有一个独立的JSESSIONIDCookie。某一个应用,不可能读取到浏览器在其他应用中的Cookie信息。

假定用户首先访问CAS Client 01,系统提醒用户进行一次登录;然后用户访问CAS Client2,不会再提示登录而是直接登录成功。

1.2第一次访问CAS Client 01

用户打开浏览器后第一次访问,重定向到单点登录后,会提示用户输入账号密码登录。登录成功之后,再跳转回CAS Client。

1.3第一次访问CAS Client 02

当用户浏览器已经登录系统,切换到另一个CASClient时,跟第一次访问有所不同,因为已经登录成功,就不会再提醒输入账号密码登录了。

1.4再次访问CAS Clients

当用户已经访问过CAS Client后,当用户再次访问,系统不会再跳转到CAS Server做认证。

1.5CASClient配置

为了实现前述的单点登录过程,以Java WEB项目为例,需要在 web.xml 中进行相应的配置。(为了排版,没有填写Filter的完整class名,请自行查阅补充。)

<filter>

  <filter-name>CAS AuthenticationFilter</filter-name>

  <filter-class>*.AuthenticationFilter</filter-class>

</filter>

<filter>

  <filter-name>CAS Validation Filter</filter-name>

  <filter-class>*.Cas10TicketValidationFilter</filter-class>

</filter>

<filter>

  <filter-name>CAS HttpServletRequest WrapperFilter</filter-name>

  <filter-class>*.HttpServletRequestWrapperFilter</filter-class>

</filter>

<filter-mapping>

  <filter-name>CAS Validation Filter</filter-name>

  <url-pattern>/*</url-pattern>

</filter-mapping>

<filter-mapping>

  <filter-name>CAS AuthenticationFilter</filter-name>

  <url-pattern>/*</url-pattern>

</filter-mapping>

<filter-mapping>

         <filter-name>CAS HttpServletRequest WrapperFilter</filter-name>

         <url-pattern>/*</url-pattern>

</filter-mapping>

仔细看一下配置过滤器可以发现,三个过滤器正好对应流程图中三次访问CAS Client。

  • Authentication Filter:负责将未登录用户跳转到登录界面
  • Authentication Filter:负责验证Service Ticket
  • HttpServletRequest WrapperFilter:负责将用户信息封装到request和session中。

2      统一注销的过程

2.1不能实现统一注销会有什么问题

当用户访问系统后从系统注销,如何能够从每个应用中都注销?注意前面1.4部分的描述,如果用户注销时,并没有注销CASClient 02中的会话信息,如果用户在浏览器中直接访问这个应用,因为Session存在,并不会提醒用户重新登录。

这会带来两个潜在的隐患:

1、  用户注销user1后换账号user2重新登录,进入CAS Client 02之后,当前身份其实还是user1,并没有如用户预期一样使用user2身份。

2、  用户user1点击注销后离开,没有关闭浏览器。这时候其他用户直接打开CAS Client 02,能够直接盗用user1的身份进行操作。

2.2基本概念:TGT和ST

CAS已经考虑到统一注销的问题。

这里有三个重要的概念TGT、ST和Service,需要着重介绍一下,因为它们同后续统一注销的方案息息相关。

2.2.1         Service

这是用户第一次访问CAS Client的URL。假设一个CAS Client应用部署在域名oa.company.com,使用HTTP协议,应用首页是index.htm。当用户第一次访问这个应用时,对应的URL地址是 http://oa.company.com/index.htm 。这个URL,对CAS Server来说,就是一个service。

当用户第一次跳转到CAS Server的时候,可以看到传了一个参数service,就是这个值。当CASServer生成Ticket重定向到CAS Client的时候,实际就是在这个service 中添加了一个参数 ticket 。

2.2.2         TGT:Ticket Grangting Ticket

TGT是CAS Server为每一个登录用户创建的登录令牌。在CASServer上拥有了TGT,用户就可以证明自己在CASServer成功登录过。TGT封装了SessionCookie值以及此Cookie值对应的用户信息。当HTTP请求到来时,CAS以此Cookie值为key查询缓存中有无TGT ,如果有的话,则相信用户已登录过。

2.2.3         ST:Service Ticket

ST是CAS Server为用户签发的访问某一service的认证令牌。用户访问service时,service发现用户没有ST,浏览器会跳转到CASServer去获取ST。CAS Server发现用户有TGT,则签发一个ST,返回给用户。用户使用ST作为ticket参数去访问service,service拿ST去CAS Server验证,验证通过后,得到当前登录用户的登录名。

注意TGT和ST,是一对多的关系。一个TGT会维护一个 services 列表,每当为用户创建一个ST并认证通过后,会将这个ST添加到TGT的services列表中。这样,在CASServer端,这个services列表实际维护了一个用户登录过的所有CASClient。这就为实现统一注销打下了基础。

2.3CAS Client的统一注销配置

CAS Client,为了实现统一注销,除了第一张介绍的三个登录过程的过滤器之外,还需要添加一个统一注销过滤器。

<filter>

 <filter-name>CAS Single Sign OutFilter</filter-name>

 <filter-class>*.SingleSignOutFilter</filter-class>

</filter>

<filter-mapping>

 <filter-name>CAS Single Sign OutFilter</filter-name>

 <url-pattern>/*</url-pattern>

</filter-mapping>

<listener>

 <listener-class>*.SingleSignOutHttpSessionListener</listener-class>

</listener>

2.4CAS Server注销过程

用户在浏览器中点击“注销”链接,实际浏览器会访问CASServer的注销页面。收到注销请求后,CAS Server会读取到TGT,并检查当前用户登录过的所有service,并依次发送注销请求。

2.5CAS Client注销过程

CAS Client的注销,核心代码是SingleSignOutFilter,它的关键代码

public voiddoFilter(servletRequest, servletResponse, filterChain){

         HttpServletRequest request =(HttpServletRequest)servletRequest;

         if (handler.isTokenRequest(request)) {

                   handler.recordSession(request);

         } else if (handler.isLogoutRequest(request)) {

                   handler.destroySession(request);

                   return;

         }

         filterChain.doFilter(servletRequest, servletResponse);

}

其中handler是SingleSignOutHandler的实例,这个对象完成用户在CASClient端登录信息的维护和注销工作。

至此,CAS完整的登录和注销过程就完成。

2.6思考:什么情况统一注销会失败

统一注销的实现,需要CAS Server通过HttpClient访问CAS Client的service。如果这个访问过程失败,就会导致统一注销失败。列了几种情况,不详述。

1、开发调试阶段,使用localhost访问CAS Client。

2、CAS Server部署在外网,CAS Client部署在内网。

3、网络安全设置,不允许CASServer访问CAS Client。

3      CAS Client集群的影响

前面的论述,一直假定所有的CAS Client都是单点部署,没有集群。如果集群,会有什么影响,应该如何来解决?

3.1Client集群对登录的影响

假设使用nginx做集群前端,后面部署两台CAS Client 01的实例。我们看看对登录过程会有什么影响。

为了描述方便,CAS Client登录过程会有三次请求(对应三个过滤器),我们依次命名为Authentication Request / Validation Request / Wrapper Request。

Nginx缺省的分发规则,并不是sticky模式,同一个浏览器的请求,会按照nginx自身某种规则进行分发。我们曾经测试过,在双点集群环境下,Authentication Request和ValidationRequest会恰好被分发到两台服务器,这就会导致登录过程死循环。

出现登录死循环的原因,主要在于nginx分发时,没有使用sticky策略,也就是同一个浏览器的请求,永远分发给同一台CAS Client实例。缺省nginx的分发策略,可以根据用户IP分发,实现的是同一个IP永远分发到同一台Client,这样就能解决死循环的问题。

3.2Client集群对注销的影响

当nginx实现了sitcky转发,同一个浏览器的访问会分发到同一个Client1实例,该用户的会话信息也一直保存在Client1实例中。

当用户统一注销时,由CAS Server向Client发送注销请求,这时候nginx无法确保按当前用户进行分发,因此可能会被分发到Client2。这时候,实际效果是注销失败。

这个问题,在我们当前的环境中真实存在,还没有合理的解决方法。初步分析,大概有几个修改方向。

3.2.1         修改nginx分发策略

问题存在的原因,是因为nginx在分发注销策略时,不能准确分发。如果能在这个环节进行修改,系统代码和环境,基本不用做任何修改。

但这个实现难度很大,而且可能会影响nginx的性能。

3.2.2         集群的节点实现Session同步

如果能实现集群Session的同步:同步创建、同步注销,主要在一个Client上实现了注销,其他Client也就同步注销。

这个会对Tomcat性能有影响。

3.2.3         集群节点使用redis保存会话信息

即使是多个节点,它们的会话信息只有一份。一旦失效,则所有节点都失效。这只是一个设想,没有做技术调研,不知能够实现。

3.2.4         每次请求验证用户是否注销

首先,在CAS Server中实现一个接口,用于判断某一个ST对应的TGT是否还有效。

在SingleSignOutFilter中,每次访问都调用CAS Server的这个新接口,判断用户是否已经注销。如果已经注销,则立刻注销本实例中的会话信息。

这个方法是比较安全的解决办法,但每次请求都会调用CASServer接口,会对性能造成巨大影响。完全不建议用这种方案。

时间: 2024-11-03 03:10:17

CAS的登录和注销原理的相关文章

CAS单点登录(SSO)完整教程

CAS单点登录(SSO)完整教程(2012-02-01更新) 一.教程说明 前言 教程目的:从头到尾细细道来单点登录服务器及客户端应用的每个步骤 单点登录(SSO):请看百科解释猛击这里打开 本教程使用的SSO服务器是Yelu大学研发的CAS(Central Authentication Server), 官网:http://www.jasig.org/cas 本教程环境: Tomcat6.0.29 JDK6 CAS Server版本:cas-server-3.4.3.1.cas-server-

JAVA CAS单点登录之三:CAS代理模式演练

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dba10g.blog.51cto.com/764602/1753244 前言  JAVA CAS单点登录之一:搭建CAS服务器     JAVA CAS单点登录之二:CAS普通模式1演练     代理模式相相对上一节的普通模式,更加复杂了.但配置起来也会稍微有些差别.所谓难者不会,会者不难.如果遇到一个从来没有遇到的问题,解决起来也是非常棘手的,当然解决之后就不是事了.我就遇到

【SSO-CAS】SSO之CAS单点登录实例演示

国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为"中国PE第一股",市值超1000亿元.    ----------------------------------------------------------------------------

CAS单点登录时AJAX页面刷新无反应(302 Moved Temporarily)

最近使用CAS做单点认证服务时发现过大概二十分钟后就发现凡是异步方式刷新页面就无反应了(由于使用EasyUI框架,所以页面刷新基于ajax+div方式),刚开始一直认为是CAS服务端超时的问题,查看了各个配置,网上也参考了许多帖子,一直没有解决,今天无意想起来是不是session过期了呢,因为单点登录客户端没有配置任何session有效时长,也就是说客户端的session时长为tomcat默认时长(网上有人说Tomcat默认session有效期为30分钟,而现在发现的是大概20分钟后就会出现用a

登录和注销HP-UX

登录帐户 本部分介绍了如何使用命令行登录.注销和创建用户帐户(如有必要). 向系统管理员或安装系统的技术支持人员询问用户名和口令. 超级用户 root 用户(又称为超级用户)是一个特殊的用户.以超级用户身份登录时,具有执行所有系统管理任务所需的权限.通常,系统管理员是唯一有权以超级用户身份登录的用户.如果您不是系统管理员,则不能以超级用户身份登录,以执行日常管理任务. Root 登录 不过,第一次登录到新工作站时,必须以 root(root 是超级用户的用户名)用户身份登录.这是因为尚未创建任何

咪咕音乐播放器如何登录与注销

  咪咕音乐播放器提供客户登录与注销,登录帐号可以同时登录12530门户网站和PC客户端.登录后可进行客户设置,将客户信息保存在客户端中.提供注销功能,在客户端生命周期内,将客户端中保留的客户信息删除.客户登录后可享受收藏歌曲.管理彩铃等个性化服务.

django用户登录和注销

django版本:1.4.21. 一.准备工作 1.新建项目和app [root@yl-web-test srv]# django-admin.py startproject lxysite [root@yl-web-test srv]# cd lxysite/ [root@yl-web-test lxysite]# python manage.py startapp accounts [root@yl-web-test lxysite]# ls accounts lxysite manage.

.net cas 单点登录 求助

问题描述 .net cas 单点登录 求助 本人花了一个多星期找资料+测试,还是实现不了这个单点登录功能.请csdn网友出手相助 外部单点登录网址:http://59.41.39.98:808/CAS_Server/login 登录帐号与密码:0166166 123456 功能描述:1.在一个自己开发的网站登录界面,输入帐号密码,实现单点登录. 2.如果1无法实现,那在打开单点登录网址,输入帐号密码登录成功后能返回本网站页面. PS:需要是.net开发的,如果有完整可用的样例源码最好,感谢..

java-关于CAS单点登录的用户认证

问题描述 关于CAS单点登录的用户认证 现有多个系统web1,web2,web3... 用户张三,在web1里用户名密码是user1/123,在web2里用户名密码是zhangsan/456,在web3里用户名密码是abc/789-- 这些多个系统的用户名密码存放在不同数据库中,但是每个数据库里都有"工号"这个字段,且为必填项. 现在将这多个系统用CAS做单点登录,这多个数据库如何通过"工号"这个字段统一? 刚看到的一个思路: 单对多模式:一个用户使用不同凭证登录不