一、何谓单点登录
单点登录(Single Sign On),简称为 SSO,简单理解就是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
二、何谓CAS
CAS(Central Authentication Service)是耶鲁大学的一个开源项目,旨在为web应用系统提供一种可靠的单点登录解决方案。采用CAS最大的是从安全性角度来考虑的,用户在CAS录入用户名和密码之后通过ticket进行认证,不会在网上传输密码,保证安全性。
CAS 介绍
CAS 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。CAS 具有以下特点:
开源的企业级单点登录解决方案。
CAS Server 为需要独立部署的 Web 应用。
CAS Client 支持非常多的客户端(这里指单点登录系统中的各个 Web 应用),包括 Java, .Net, PHP, Perl, Apache, uPortal, Ruby 等。
CAS 原理和协议
从结构上看,CAS 包含两个部分: CAS Server 和 CAS Client。CAS Server 需要独立部署,主要负责对用户的认证工作;CAS Client 负责处理对客户端受保护资源的访问请求,需要登录时,重定向到 CAS Server。图1 是 CAS 最基本的协议过程:
CAS Client 与受保护的客户端应用部署在一起,以 Filter 方式保护受保护的资源。对于访问受保护资源的每个 Web 请求,CAS Client 会分析该请求的 Http 请求中是否包含 Service Ticket,如果没有,则说明当前用户尚未登录,于是将请求重定向到指定好的 CAS Server 登录地址,并传递 Service (也就是要访问的目的资源地址),以便登录成功过后转回该地址。用户在第 3 步中输入认证信息,如果登录成功,CAS Server 随机产生一个相当长度、唯一、不可伪造的 Service Ticket,并缓存以待将来验证,之后系统自动重定向到 Service 所在地址,并为客户端浏览器设置一个 Ticket Granted Cookie(TGC),CAS Client 在拿到 Service 和新产生的 Ticket 过后,在第 5,6 步中与 CAS Server 进行身份合适,以确保 Service Ticket 的合法性。
在该协议中,所有与 CAS 的交互均采用 SSL 协议,确保,ST 和 TGC 的安全性。协议工作过程中会有 2 次重定向的过程,但是 CAS Client 与 CAS Server 之间进行 Ticket 验证的过程对于用户是透明的。
另外,CAS 协议中还提供了 Proxy (代理)模式,以适应更加高级、复杂的应用场景,具体介绍可以参考 CAS 官方网站上的相关文档。
三、CAS中的关键词理解
CAS的核心就是其Ticket,及其在Ticket之上的一系列处理操作。CAS的主要票据有TGT、ST、PGT、PGTIOU、PT,其中TGT、ST是CAS1.0协议中就有的票据,PGT、PGTIOU、PT是CAS2.0协议中有的票据。
TGT(Ticket Grangting Ticket)
TGT是CAS为用户签发的登录票据,拥有了TGT,用户就可以证明自己在CAS成功登录过。TGT封装了Cookie值以及此Cookie值对应的用户信息。用户在CAS认证成功后,CAS生成cookie,写入浏览器,同时生成一个TGT对象,放入自己的缓存,TGT对象的ID就是cookie的值。当HTTP再次请求到来时,如果传过来的有CAS生成的cookie,则CAS以此cookie值为key查询缓存中有无TGT ,如果有的话,则说明用户之前登录过,如果没有,则用户需要重新登录。
ST(Service Ticket)
ST是CAS为用户签发的访问某一service的票据。用户访问service时,service发现用户没有ST,则要求用户去CAS获取ST。用户向CAS发出获取ST的请求,如果用户的请求中包含cookie,则CAS会以此cookie值为key查询缓存中有无TGT,如果存在TGT,则用此TGT签发一个ST,返回给用户。用户凭借ST去访问service,service拿ST去CAS验证,验证通过后,允许用户访问资源。
PGT(Proxy Granting Ticket)
Proxy Service的代理凭据。用户通过CAS成功登录某一Proxy Service后,CAS生成一个PGT对象,缓存在CAS本地,同时将PGT的值(一个UUID字符串)回传给Proxy Service,并保存在Proxy Service里。Proxy Service拿到PGT后,就可以为Target Service(back-end service)做代理,为其申请PT。
PGTIOU(Proxy Granting Ticket IOU)
PGTIOU是CAS协议中定义的一种附加票据,它增强了传输、获取PGT的安全性。
PGT的传输与获取的过程:Proxy Service调用CAS的serviceValidate接口验证ST成功后,CAS首先会访问pgtUrl指向的https url,将生成的 PGT及PGTIOU传输给proxy service,proxy service会以PGTIOU为key,PGT为value,将其存储在Map中;然后CAS会生成验证ST成功的xml消息,返回给Proxy Service,xml消息中含有PGTIOU,proxy service收到Xml消息后,会从中解析出PGTIOU的值,然后以其为key,在map中找出PGT的值,赋值给代表用户信息的Assertion对象的pgtId,同时在map中将其删除。
PT(Proxy Ticket)
PT是用户访问Target Service(back-end service)的票据。如果用户访问的是一个Web应用,则Web应用会要求浏览器提供ST,浏览器就会用cookie去CAS获取一个ST,然后就可以访问这个Web应用了。如果用户访问的不是一个Web应用,而是一个C/S结构的应用,因为C/S结构的应用得不到cookie,所以用户不能自己去CAS获取ST,而是通过访问proxy service的接口,凭借proxy service的PGT去获取一个PT,然后才能访问到此应用。
Session
各个应用系统会创建自己的session表示是否登录,而这里的每个session都是ST验证通过之后组装生成的。
TGT、ST、PGT、PT之间关系
1、ST是TGT签发的。用户在CAS上认证成功后,CAS生成TGT,用TGT签发一个ST,ST的ticketGrantingTicket属性值是TGT对象,然后把ST的值redirect到客户应用。
2、PGT是ST签发的。用户凭借ST去访问Proxy service,Proxy service去CAS验证ST(同时传递PgtUrl参数给CAS),如果ST验证成功,则CAS用ST签发一个PGT,PGT对象里的ticketGrantingTicket是签发ST的TGT对象。
3、PT是PGT签发的。Proxy service代理back-end service去CAS获取PT的时候,CAS根据传来的pgt参数,获取到PGT对象,然后调用其grantServiceTicket方法,生成一个PT对象。
四、CAS实现原理
假设我们现在有应用系统A、应用系统B、CAS认证系统
1、第一次访问系统A时,没有票据(ST),也没有session,会重定向到CAS服务器,要求用户输入用户名和密码,之后CAS向浏览器写入TGC,同时生成TGT保存到缓存,CAS服务器会根据TGT生成ST,然后CAS会重定向到给应用系统A,CAS将这个ST和成功登录的用户,以及服务联系在一起。这个ST使用次数(numberOfUses)和有效时间(timeToKill)是可配置的,超过设置的次数或者超过有效时间就会失效。
2、应用系统A收到这个ST之后,它并不知道这个用户已经登录成功,就通过将ST 传递给一个校验URL,校验URL拿到Cas系统去验证,CAS通过验证之后返回用户信息,并且将ST作废。
3、应用系统A根据从CAS收到的用户信息将session创建起来,这样我们的应用就拥有了一个自己的session。
4、第一次访问另一个应用系统B,也是没有票据(ST),也没有session,会再次被重定向到CAS系统,CAS系统会去获得TGC,如果该TGC没有失效,则拿到TGT生成ST给用户重定向到系统B,系统B拿到ST之后再去CAS系统验证(同应用系统B的验证方式),验证成功则创建session;如果 TGC 失效,那么用户还是要重新认证。
5、再去访问系统A时,没有票据,因为票据只能用一次,但是我们有session,所以不用跳转到CAS去签发票据了,直接允许用户访问。
6、用户登出的时候,CAS系统接受请求后,会检测用户的TGC,把对应的session清除,同时会找到所有通过该TGC进行SSO登录的应用服务器URL提交请求,所有的回调请求中,包含一个参数logoutRequest,内容格式如下:
<samlp:LogoutRequest ID="[RANDOMID]" Version="2.0" IssueInstant="[CURRENTDATE/TIME]"> <saml:NameID>@NOT_USED@</saml:NameID> <samlp:SessionIndex>[SESSIONIDENTIFIER]</samlp:SessionIndex> </samlp:LogoutRequest>
所有收到请求的应用服务器会解析这个参数,取得sessionId,根据这个Id取得session后,把session清除。
五、认证相关的概念及流程
Credentials:用户提供的用于登录用的凭据信息,如用户名/ 密码、证书、IP 地址、Cookie 值等。比如 UsernamePasswordCredentials ,封装的是用户名和密码。CAS 进行认证的第一步,就是把从UI 或request 对象里取到的用户凭据封装成Credentials 对象,然后交给认证管理器去认证。
AuthenticationHandler:认证Handler, 每种AuthenticationHandler 只能处理一种Credentials ,如AbstractUsernamePasswordAuthenticationHandler 只负责处理 U sernamePasswordCredentials 。
Principal:封装用户标识,比如 SimplePrincipal, 只是封装了用户名。认证成功后, credentialsToPrincipalResolvers 负责由Credentials 生成 Principal 对象。
CredentialsToPrincipalResolvers:负责由 Credentials 生成 Principal 对象,每种 CredentialsToPrincipalResolvers 只处理 一种Credentials ,比如 UsernamePasswordCredentialsToPrincipalResolver 负责从 U sernamePasswordCredentials 中取出用户名,然后将其赋给生成的 SimplePrincipal 的 ID 属性。
AuthenticationMetaDataPopulators:负责将 Credentials 的一些属性赋值给 Authentication 的 attributes 属性。
Authentication:认证管理器的最终处理结果,Authentication 封装了 Principal,认证时间,及其他一些属性(可能来自Credentials )。
AuthenticationManager:认证管理器得到 Credentials 对象后,负责调度AuthenticationHandler 去完成认证工作,最后返回的结果是 Authentication 对象。
CentralAuthenticationService:CAS 的服务类,对 Web 层提供了一些方法。该类还负责调用 AuthenticationManager 完成认证逻辑。
CAS 基本流程图(没有使用PROXY代理)
3. 使用代理的 CAS 流程图
参考文章:
http://www.cnblogs.com/vhua/tag/sso/
http://www.cnblogs.com/zzhuyongxin/tag/cas/