CAS调研总结

本篇文章是对JA-SIG CAS(v3.3)的初步调研总结。

一配置实例

应用场景: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.90

   hosts配置: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.90

   hosts配置:192.168.7.115  cas.mycompany.com

   web.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/cas

CAS的主要文档:

http://www.ja-sig.org/wiki/display/CASUM/Home

http://www.jasig.org/cas/cas1-architecture

http://www.jasig.org/cas/cas2-architecture

http://www.jasig.org/cas/protocol/

http://www.ja-sig.org/wiki/display/CASUM/Demo

CAS调研总结_第1张图片

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默认的登录处理流程


CAS调研总结_第2张图片

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

CAS调研总结_第3张图片

               已经登录web1后,访问web1的资源(web1没有启动session),或访问web2的资源

注:

1:InitialFlowSetupAction: 是流程的入口。用request.getContextPath()的值来设置cookiePath值,Cookiepath值是在配置文件里定义的,但这个Action负责将request.getContextPath()的值设置为Cookiepath值,这是在cas部署环境改变的情况下,灵活地设置cookie path的方式;把cookie的值以及service参数的值放入requestContextflowscope里。

2GenerateServiceTicketAction Action负责根据serviceGTC cookie值生成ServiceTicket对象,ServiceTicketID就是返回给客户应用的ticket参数,如果成功创建ServiceTicket,则转发到WarnAction,如果创建失败,且gateway参数为true,则直接redirect到客户应用,否则则需要重新认证。

3viewLoginForm 这是登录页面,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 只负责处理UsernamePasswordCredentials
  • Principal 封装用户标识,比如SimplePrincipal, 只是封装了用户名。认证成功后,credentialsToPrincipalResolvers 负责由Credentials生成Principal 对象。
  • CredentialsToPrincipalResolvers 负责由Credentials生成Principal 对象,每种CredentialsToPrincipalResolvers 只处理一种Credentials,比如UsernamePasswordCredentialsToPrincipalResolver负责从UsernamePasswordCredentials 中取出用户名,然后将其赋给生成的SimplePrincipal ID 属性。
  • AuthenticationMetaDataPopulators 负责将Credentials的一些属性赋值给Authentication attributes 属性。
  • Authentication  Authentication是认证管理器的最终处理结果,Authentication 封装了Principal ,认证时间,及其他一些属性(可能来自Credentials )。
  • AuthenticationManager 认证管理器得到Credentials对象后,负责调度AuthenticationHandler去完成认证工作,最后返回的结果是Authentication 对象。
  • CentralAuthenticationService  CAS 的服务类,对Web 层提供了一些方法。该类还负责调用AuthenticationManager 完成认证逻辑

序列图


CAS调研总结_第4张图片

CAS认证处理序列图

类图


CAS调研总结_第5张图片

CAS认证类图

你可能感兴趣的:(CAS调研总结)