您的位置:首页 > 其它

CAS认证原理分析(1)

2014-04-14 17:07 253 查看

一 配置实例

应用场景: cas 服务部署在192.168.7.115 ,是一个web 应用,访问地址为:https://cas.mycompany.com:8443/cas/ 。web1应用位于192.168.7.90 ,访问地址为:http://192.168.7.90:8081/web1 ,web2 应用位于192.168.7.90 ,访问地址为:http://192.168.7.90:8082/web2 。web1 和web2 通过cas 服务实现SSO 功能。浏览器位于本地localhost 。
cas 服务器: 192.168.7.115 启动8443 端口,需配置证书
web1 : 192.168.7.90hosts配置: 192.168.7.115 cas.mycompany.com web.xml里的配置: <context-param> <param-name>casServerUrlPrefix</param-name> <param-value>https://cas.mycompany.com:8443/cas/</param-value> </context-param> <context-param> <param-name>serverName</param-name> <param-value>192.168.7.90:8081</param-value> </context-param> <filter> <filter-name>CAS Authentication Filter</filter-name><filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <init-param> <param-name>casServerLoginUrl</param-name> <param-value>https://cas.mycompany.com:8443/cas/login</param-value> </init-param> </filter> <filter> <filter-name>CAS Validation Filter</filter-name> <filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Authentication Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
JDK启动参数需加上( 验证CAS 服务器证书的需要) : -Djavax.net.ssl.trustStore=/home/yz/web1/conf/cas-client-trust-cert.jks -Djavax.net.ssl.trustStorePassword=casclient!@#
web2 : 192.168.7.90hosts配置: 192.168.7.115 cas.mycompany.comweb.xml里的配置: 同web1 里web.xml 的配置,只是serverName 属性的值变成了192.168.7.90:8082
JDK 启动参数需加上( 验证CAS 服务器证书的需要) : -Djavax.net.ssl.trustStore=/home/yz/web2/conf/cas-client-trust-cert.jks -Djavax.net.ssl.trustStorePassword=casclient!@#
本地 :hosts 配置: 192.168.7.115 cas.mycompany.com
注:1 casServerLoginUrl 参数的值是cas 服务器login 接口的值。web 应用里的cas client 在认证的时候会redirect 到 cas 服务器,redirect 的url 就是casServerLoginUrl ,因为是redirect ,所以浏览器所在机器要配置cas 服务器的域名。2 casServerUrlPrefix 参数的值是cas 服务的访问地址。cas client 验证ticket 的时候,要访问cas 服务的/serviceValidate 接口,使用的url 就是${ casServerUrlPrefix }serviceValidate ,因为客户web 应用要验证cas 的证书,所以证书cn 字段的值必须和casServerUrlPrefix 里设置的cas 服务器的域名保持一致,并且在web 应用的服务器上配置cas 服务的访问域名。2 serverName 参数,cas client 会用来生成service 参数,并且cas 服务器在认证通过、ticket 验证通过后,会redirect到web 应用,redirect 的url 就是service 参数的值。serverName 参数可以是IP ,也可以是域名,只要保证浏览器能访问到即可。

二 CAS 简单介绍

CAS 官方网站: http://www.jasig.org/casCAS 的主要文档:http://www.ja-sig.org/wiki/display/CASUM/Homehttp://www.jasig.org/cas/cas1-architecturehttp://www.jasig.org/cas/cas2-architecturehttp://www.jasig.org/cas/protocol/http://www.ja-sig.org/wiki/display/CASUM/Demo

CAS 官方网站上的介绍图
主要原理:用户第一次访问一个CAS 服务的客户web 应用时(访问URL :http://192.168.7.90:8081/web1 ),部署在客户web应用的cas AuthenticationFilter ,会截获此请求,生成service 参数,然后redirect 到CAS 服务的login 接口,url为https://cas:8443/cas/login?service=http%3A%2F%2F192.168.7.90%3A8081%2Fweb1%2F ,认证成功后,CAS 服务器会生成认证cookie ,写入浏览器,同时将cookie 缓存到服务器本地,CAS 服务器还会根据service 参数生成ticket,ticket 会保存到服务器,也会加在url 后面,然后将请求redirect 回客户web 应用,url 为http://192.168.7.90:8081/web1/?ticket=ST-5-Sx6eyvj7cPPCfn0pMZuMwnbMvxpCBcNAIi6-20 。这时客户端的AuthenticationFilter 看到ticket 参数后,会跳过,由其后面的TicketValidationFilter 处理,TicketValidationFilter 会利用httpclient 工具访问cas 服务的/serviceValidate 接口, 将ticket、service 都传到此接口,由此接口验证ticket 的有效性,TicketValidationFilter 如果得到验证成功的消息,就会把用户信息写入web 应用的session 里。至此为止,SSO 会话就建立起来了,以后用户在同一浏览器里访问此web 应用时,AuthenticationFilter 会在session 里读取到用户信息,所以就不会去CAS 认证,如果在此浏览器里访问别的web 应用时,AuthenticationFilter 在session 里读取不到用户信息,会去CAS 的login 接口认证,但这时CAS 会读取到浏览器传来的cookie ,所以CAS 不会要求用户去登录页面登录,只是会根据service 参数生成一个ticket ,然后再和web 应用做一个验证ticket的交互而已。

二 CAS 客户端 Filter 的处理逻辑

1 AuthenticationFilter if(url 中无ticket 参数 && session 中没有TicketValidationFilter 置的assertion 对象){ response.sendRedirect(cas 服务器的/login 接口);// 生成service 参数,添加到url 后面 } else{ 不做处理 }
2 TicketValidationFilter if(url 中有ticket 参数){ 通过httpclient 工具访问cas 服务器的/serviceValidate 接口验证ticket 的有效性,验证失败,显示错误页面,验证成功,则生成标识用户身份的assertion 对象,放入session 。 } else{ 不做处理 }
注:1 AuthenticationFilter 在前,TicketValidationFilter 在后。2 AuthenticationFilter : 1 )url 中无ticket 参数,且session 中没有TicketValidationFilter 置的assertion 对象,这种情况说明用户还没有认证,AuthenticationFilter 会去做认证处理; 2 )url 中无ticket 参数,且session 中有TicketValidationFilter 置的assertion 对象,这种情况说明用户已经认证成功,AuthenticationFilter 不做处理; 3 )url 中有ticket 参数,这种情况说明用户已经认证成功,但还需要经TicketValidationFilter 去验证ticket,AuthenticationFilter不做处理。3 TicketValidationFilter :只有客户端调用cas 服务器的/login 接口, 并成功认证,redirect 回客户端时,url 里才带有ticket 参数,在这种情况下,TicketValidationFilter 才做处理。

三 CAS 服务端的处理逻辑

CAS 服务端总共对外暴露了7 个接口,客户端通过访问这7 个接口与服务端交互,这7 个接口为:/login 、/logout 、/validate、/serviceValidate 、/proxy 、/proxyValidate 、/CentralAuthenticationService 。/login 是认证接口,/logout 是退出接口,负责销毁认证cookie,/validate 、/serviceValidate 是验证ticket 用的接口,其中/validate 是CAS1.0 定义的,/serviceValidate是CAS2.0 定义的,其中/serviceValidate 返回xml 格式的数据,/proxy 、/proxyValidate 是支持代理认证功能的接口,/CentralAuthenticationService 接口用于和远程的web services 交互。对于一般web 应用的单点登录来讲,/login、/logout 、/serviceValidate 这3 个接口已经可以满足要求 。CAS 协议中已经对这些接口做了定义,链接为:http://www.jasig.org/cas/protocol 。下面是我对CAS 各个接口实现的的详细说明。
/login:登录流程这部分要考虑到不同种类用户凭证的获取方案,以及客户应用传来的service 、gateway 、renew 参数的不同取值组合,CAS 为了实现流程的高度可配置性,采用了Spring Web Flow 技术。通过阅读CAS 发布包里的login-webflow.xml 、cas-servlet.xml 、applicationContext.xml 这3 个文件,我找出 了登录有关的所有组件,并画出了它的处理流程图。



CAS 默认的登录处理流程


第一次访问Web 应用的流程走向


已经登录web1 后,访问web1 的资源(web1 没有启动session ),或访问web2 的资源
注:1 : InitialFlowSetupAction: 是流程的入口。用 request.getContextPath() 的值来设置 cookie 的 Path 值, Cookie 的 path 值是在配置文件里定义的,但这个 Action 负责将 request.getContextPath() 的值设置为 Cookie 的 path 值,这是在 cas 部署环境改变的情况下,灵活地设置 cookie path 的方式;把 cookie 的值以及 service 参数的值放入 requestContext 的 flowscope 里。2 : GenerateServiceTicketAction 此 Action 负责根据 service 、 GTC cookie 值生成 ServiceTicket 对象, ServiceTicket 的 ID就是返回给客户应用的 ticket 参数,如果成功创建 ServiceTicket ,则转发到 WarnAction ,如果创建失败,且 gateway 参数为true ,则直接 redirect 到客户应用, 否则则需要重新认证。3 : viewLoginForm 这是登录页面, CAS 在此收集用户凭证。 CAS 提供的默认实现是 /WEB-INF/view/jsp/simple/ui/casLoginView.jsp 。4 : bindAndValidate 对应 AuthenticationViaFormAction 的 doBind 方法,该方法负责搜集登录页面上用户录入的凭证信息(用户名、密码等),然后把这些信息封装到 CAS 内部的 Credentials 对象中。用户在 casLoginView.jsp 页面上点击提交后,会触发此方法。5:submit 对应 AuthenticationViaFormAction 的 submit 方法 , 如果 doBind 方法成功执行完, 则触发 submit 方法,此方法负责调用 centralAuthenticationService 的 grantServiceTicket 方法,完成认证工作,如果认证成功,则生成TicketGrantingTicket 对象,放在缓存里, TicketGrantingTicket 的 ID 就是 TGC Cookie 的 value 值。6 : warn CAS 提供了一个功能:用户在一个 web 应用中跳到另一个 web 应用时, CAS 可以跳转到一个提示页面,该页面提示用户要离开一个应用进入另一个应用,可以让用户自己选择。用户在登录页面 viewLoginForm 上选中了 id=”warn” 的复选框,才能开启这个功能。WarnAction 就检查用户有没有开启这个功能,如果开启了,则转发到showWarnView, 如果没开启,则直接redirect 到客户应用。7 :SendTicketGrantingTicketAction 此Action 负责为response 生成TGC Cookie ,cookie 的值就是AuthenticationViaFormAction 的 submit 方法生成的 TicketGrantingTicket 对象的 ID 。8 : viewGenerateLoginSuccess 这是 CAS 的认证成功页面。

/logout: 对应实现类 org.jasig.cas.web.LogoutController ) 处理逻辑: 1) removeCookie 2) 在服务端删除TicketGrantingTicket 对象(此对象封装了cookie 的value 值) 3 )redirect 到退出页面,有2 种选择: if(LogoutController 的followServiceRedirects 属性为true 值,且url 里的service 参数非空){ redirect 到 sevice 参数标识的url } else{ redirect 到内置的casLogoutView (cas/WEB-INF/view/jsp/default/ui/casLogoutView.jsp ),如果url 里有url 参数,则此url 参数标识的链接会显示在casLogoutView 页面上。 }/serviceValidate: (对应实现类 org.jasig.cas.web.ServiceValidateController ) 处理逻辑: 如果service 参数为空或ticket 参数为空,则转发到failureView (/WEB-INF/view/jsp/default/protocol/2.0/casServiceValidationFailure.jsp ) 验证ticket 。以ticket 为参数,去缓存里找ServiceTicketImpl 对象,如果能找到,且没有过期,且ServiceTicketImpl 对象对应的service 属性和service 参数对应,则验证通过,验证通过后,请求转发至casServiceSuccessView (cas/WEB-INF/view/jsp/default/protocol/2.0/casServiceValidationSuccess.jsp ),验证不通过,则转发到failureView 。

四 认证相关的概念及流程

概念

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是认证管理器的最终处理结果, Authentication 封装了 Principal ,认证时间,及其他一些属性(可能来自 Credentials )。

AuthenticationManager 认证管理器得到 Credentials 对象后,负责调度AuthenticationHandler 去完成认证工作,最后返回的结果是 Authentication 对象。

CentralAuthenticationService CAS 的服务类,对 Web 层提供了一些方法。该类还负责调用 AuthenticationManager 完成认证逻辑

序列图


CAS 认证处理序列图

类图


CAS 认证类图
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: