剖析CAS Proxy的设计原理

    由于CAS在开源社区的影响力,它逐渐被应用到各种复杂的SSO环境中。CAS的基本原理在广州UserGroup上有很多文章介绍,我不再做原理性的探讨,但CAS Proxy稍微复杂,值得对其作一个剖析,以便在日后的配置中减少配置上的失误。
    1,CAS Proxy的目的
    CAS Proxy的目的是,当浏览器用户Peter访问应用A,应用A引用了应用B1, B2的授权性资源(Authorized Resource),应用A想代表Peter去访问应用B1, B2,因此应用A需要告诉应用B1, B2当前用户是谁,以便B1,B2对Peter的Request进行授权。这就是CAS代理(Proxy)。

    这种情况很可能出Portal中,比如我在一个Web应用中要求同时从mail.163.com(应用B1),mail.126.com(应用B2)收取邮件并Load入到现在的应用A中去。这种场景中,应用A不可能分别Redirect用户Peter到163.com或者126.com去(因为用户是想要A展示B1,B2的内容,他并不是要访问163,126),只不过B1,B2需要认证才能访问,因此,A承担着这样一个角色,代表用户peter去load B1,B2的邮件。

    2,CAS Proxy的执行场景
    CAS Proxy协议很准确的描述了这种场景,简单起见,将场景分为两Part:

    PartA[获取PGT]:


    什么是PGT,PGT就是不需要S,T就能获取到NetID的票据,如果你对票据(Ticket),服务票据
等概念不理解,建议请阅读<Weblogic Security In Action>中篇的Kerberos协议部分。

    简单的说,票据(Ticket)就是一张门票,你来看周杰伦的演唱会,你需要门票,那门票叫做
Ticket,本文中的T,周杰伦演唱会就是S(Service)。
    你凭什么拿到T,当然不是因为你懂Java,而是因为你是周杰伦的VIP Fans,VIP Fans有VIP卡(即文中的C, Credential,中文翻译叫做凭证),他凭这个C可以拿到票(T),注意,是S Service(周杰伦演唱会)而不是Z Service(李宇春演唱会)或者Y Service (张靓颖演唱会)! 这个T比较巧妙,类似地铁票,CAS将它设计成一次性的票据,周杰伦拿着它给CAS Server一验证,便知道你是谁了(NetID),恩,原来是VIP Fans,欢迎欢迎........
    这本来就是CAS基本模式了,本模式还附属了一个PGTURL和PGT(PGTIOU仅仅用于关联作用,忽略),搞清楚PGT和PGTURL,是成功配置CAS Proxy的关键。
    PGT的概念(我不敢打比喻了)是,它被应用A用来代理浏览器用户Peter去访问其他更多的应用的凭据。没错,它是一个凭据,你知道,CAS/Kerberos的世界,做任何事情都需要凭据(Ticket)。所以,如果A要做这个代理访问动作,它依赖于PGT,PGT的用法见PartB,这里你知需要明白,PGT是给A用来向B1, B2两个应用证实用户Peter的身份,至于B1,B2怎么做,那还要看Peter的NetID是否具有取B1, B2邮件的权限。




    PartB[获取PGT]:

    PartB展示了PGT的作用,应用A(下图中的Web application)向CAS Server提交S和PGT,S乃自己的应用标识,PGT最终让A获得PT,PT跟ST的作用一模一样,它也是一次性的票据,A传PT给后端的B1(下图中的Back-end application),B1就可以根据这个PT获得A现在代理的用户Peter的NetID了,如下图所示。



 
    最后,我们比较一下PartA和PartB
    PartA,A因为ST获得Peter的NetID
    PartB,B1因为PT获得Peter的NetID

    谁告诉B1 Peter的NetID, A!Proxy的由来就是这样,A就是CAS Proxy!!

    有人问,干嘛这么麻烦,既然PartA中,A已经知道Perter的NetID,为何不直接告诉B1关于Peter的NetID?
    理由很简单,SSO依赖于域的一种信任关系,也就是,
    1)浏览器用户是不可信的,如果可信,那么认证要来干什么?
    2)CAS Server是可信的,如果CAS Server不可信,认证会有结果吗?
    3)Web应用可信吗?如果你认为可信,那么你就会问上面那个问题,呵呵。


    事实上,在CAS实际环境中,CAS仅仅依赖于信任证书的部署和双向SSL来实现信任关系的建立和核实。应用A和应用B是完全不同的两个应用,他们之间并没有建立信任关系,因此如果A告诉B1, B2关于Peter的NetID, B1,B2也不会相信,B1,B2只信任CAS Server(CAS环境唯一可以信赖的东西,这就是单点登录的前置条件——单点信任),最终,问题仍然需要A向通过CAS Server向B提交一个Peter身世(NetID)的说法。

    3, Proxy配置

    CAS Client端:
    配置Web应用的web.xml使用casclient.jar的两个servlet:

       <   servlet   >  
    
  <   servlet-name   >   ProxyTicketReceptor   </   servlet-name   >  
    
  <   servlet-class   >   edu.yale.its.tp.cas.proxy.ProxyTicketReceptor   </   servlet-class   >  
  
  </   servlet   >  
 
  
  <   servlet-mapping   >  
    
  <   servlet-name   >   ProxyTicketReceptor   </   servlet-name   >  
    
  <   url-pattern   >   /CasProxyServlet   </   url-pattern   >  
  
  </   servlet-mapping   >

    
    另外,在CAS Server端,确保CAS-Server的两个关于Proxy的Servlet能够正常被加载(默认配置即可)。

         <!--   Proxy (PGT acquisition)  -->  
    
  <   servlet   >  
      
  <   servlet-name   >   Proxy   </   servlet-name   >  
      
  <   servlet-class   >   edu.yale.its.tp.cas.servlet.Proxy   </   servlet-class   >  
    
  </   servlet   >  
 
    
  <!--   Modern proxy-service validation  -->  
    
  <   servlet   >  
      
  <   servlet-name   >   ProxyValidate   </   servlet-name   >  
      
  <   servlet-class   >   edu.yale.its.tp.cas.servlet.ProxyValidate   </   servlet-class   >  
    
  </   servlet   >

    最后一步,先Look一下如何单步调试CAS Proxy的 过程,然后就可以自己编写一个简单的应用A和应用B1,B2来测试CAS Proxy了。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
cas 配置client 1.0 &2.0 及proxy DEMO 说明 1 cas server 搭建 1.1 资源准备 cas server 下载 http://www.ja-sig.org/downloads/cas/cas-server-3.3.1-release.zip 1.2 解压后打开cas-server-3.3.1-release\cas-server-3.3.1\modules ,将cas-server-webapp-3.3.1.war 重命名为cas.war,并将war包拷贝到tomcat5.5以上版本的webapps目录下(在此对server jdbc支持不做详细解读,测试使用CAS simaple提供的默认用户名 密码 cas/cas) 2 证书生成及导入 2.1 Server端证书配置 2.2 2.2.1 证书生成导入 2.2.1.1 keytool -delete -alias tomcatsso -keystore cacerts -storepass changeit 2.2.1.2 keytool -list -keystore cacerts -storepass changeit 2.2.1.3 keytool -genkey -keyalg RSA -alias tomcatsso -dname "cn=www.test.com" -keystore cacerts -storepass changeit 2.2.1.4 keytool -export -alias tomcatsso -file tomcatsso.crt -keystore cacerts -storepass changeit 2.2.1.5 keytool -import -alias tomcatsso -file tomcatsso.crt -keystore cacerts -storepass changeit 2.2.1.6 keytool -list -keystore cacerts -storepass changeit 说明:在生成key的过程,"cn=www.test.com" 中的www.test.com为Server端的域名(必填)。 2.2.2 TOMCAT 配置SSL支持 2.2.2.1 将cacerts文件复制到TOMCAT的conf目录下修改server.xml <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="443" /> <Connector port="443" minSpareThreads="5" maxSpareThreads="75" enableLookups="true" disableUploadTimeout="true" acceptCount="100" maxThreads="200" scheme="https" secure="true" SSLEnabled="true" clientAuth="false" sslProtocol="TLS" keystoreFile="conf/cacerts" keystorePass="changeit" truststoreFile="conf/cacerts"/> 启动Tomcat,测试https://www.test.com:443 2.2.3 客户端证书导入 2.2.3.1 .\jre\lib\security>keytool -import -alias tomcatsso -file tomcatsso.crt -keystore cacerts -storepass changeit 3 cas client 1.0配置说明 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <description>cas1 demo</description> <!-- cas filter --> <filter> <filter-name>CAS Filter</filter-name> <filter-class> edu.yale.its.tp.cas.client.filter.CASFilter </filter-class> <!-- server login url --> <init-param> <param-name> edu.yale.its.tp.cas.client.filter.loginUrl </param-name> <param-value> https://www.test.com:8443/cas/login </param-value> </init-param> <!-- server validate url --> <init-param> <param-name> edu.yale.its.tp.cas.client.filter.validateUrl </param-name> <param-value> https://www.test.com:8443/cas/proxyValidate </param-value> </init-param> <!-- local web url --> <init-param> <param-name> edu.yale.its.tp.cas.client.filter.serverName </param-name> <param-value>www.teste.com:8080</param-value> </init-param> </filter> <!-- CAS Filter mapping --> <filter-mapping> <filter-name>CAS Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> 4 cas client 2.0配置说明 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <description>cas client test</description> <!--CAS Authentication FILTER --> <filter> <filter-name>CAS Authentication Filter</filter-name> <filter-class> org.jasig.cas.client.authentication.AuthenticationFilter </filter-class> <!-- cas server LOGIN URL --> <!-- https://www.test.com:8443/cas/login--> <init-param> <param-name>casServerLoginUrl</param-name> <param-value> https://www.test.com:8443/cas/login </param-value> </init-param> <!-- local web URL --> <init-param> <param-name>serverName</param-name> <param-value>http://www.testd.com:8080</param-value> </init-param> </filter> <!-- CAS Validation FILTER --> <filter> <filter-name>CAS Validation Filter</filter-name> <filter-class> org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter </filter-class> <!-- CAS SERVER URL --> <!-- https://www.test.com:8443/cas --> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>https://www.test.com:8443/cas</param-value> </init-param> <!-- LOCAL web URL --> <init-param> <param-name>serverName</param-name> <param-value>http://www.testd.com:8080</param-value> </init-param> <!-- if validation false throw exception ; default true--> <init-param> <param-name>exceptionOnValidationFailure</param-name> <param-value>false</param-value> </init-param> </filter> <!-- cas security username on request.getRemoteUser() --> <filter> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <filter-class> org.jasig.cas.client.util.HttpServletRequestWrapperFilter </filter-class> </filter> <!-- CAS SINGLE SIGN OUT FILTER --> <filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class> org.jasig.cas.client.session.SingleSignOutFilter </filter-class> </filter> <filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Authentication Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <url-pattern>/index.jsp</url-pattern> </filter-mapping> <!-- SingleSignOutHttpSessionListener LISTENER --> <listener> <listener-class> org.jasig.cas.client.session.SingleSignOutHttpSessionListener </listener-class> </listener> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> 5 cas client 2.0 proxy 配置说明 proxy web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <description>cas client test</description> <!--CAS Authentication FILTER --> <filter> <filter-name>CAS Authentication Filter</filter-name> <filter-class> org.jasig.cas.client.authentication.AuthenticationFilter </filter-class> <!-- cas server LOGIN URL --> <!-- http://www.test.com:8880 --> <init-param> <param-name>casServerLoginUrl</param-name> <param-value> https://www.test.com:8443/cas/login </param-value> </init-param> <!-- local web URL --> <init-param> <param-name>serverName</param-name> <param-value>http://www.teste.com:8080</param-value> </init-param> </filter> <!-- CAS Validation FILTER --> <filter> <filter-name>CAS Validation Filter</filter-name> <filter-class> org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter </filter-class> <!-- CAS SERVER URL --> <!-- http://www.test.com:8880 --> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>https://www.test.com:8443/cas</param-value> </init-param> <!-- LOCAL web URL --> <init-param> <param-name>serverName</param-name> <param-value>http://www.teste.com:8080</param-value> </init-param> <!-- if validation false throw exception ; default true--> <init-param> <param-name>exceptionOnValidationFailure</param-name> <param-value>false</param-value> </init-param> <!-- the URL to watch for PGTIOU/PGT responses from the CAS server --> <init-param> <param-name>allowedProxyChains</param-name> <param-value>http://www.testd.com:8080/testd</param-value> </init-param> </filter> <!-- cas security username on request.getRemoteUser() --> <filter> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <filter-class> org.jasig.cas.client.util.HttpServletRequestWrapperFilter </filter-class> </filter> <!-- CAS SINGLE SIGN OUT FILTER --> <filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class> org.jasig.cas.client.session.SingleSignOutFilter </filter-class> </filter> <filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <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> <filter-mapping> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <url-pattern>/index.jsp</url-pattern> </filter-mapping> <!-- SingleSignOutHttpSessionListener LISTENER --> <listener> <listener-class> org.jasig.cas.client.session.SingleSignOutHttpSessionListener </listener-class> </listener> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> non proxy web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <description>cas client test</description> <!--CAS Authentication FILTER --> <filter> <filter-name>CAS Authentication Filter</filter-name> <filter-class> org.jasig.cas.client.authentication.AuthenticationFilter </filter-class> <!-- cas server LOGIN URL --> <!-- https://www.test.com:8443/cas/login--> <init-param> <param-name>casServerLoginUrl</param-name> <param-value> https://www.test.com:8443/cas/login </param-value> </init-param> <!-- local web URL --> <init-param> <param-name>serverName</param-name> <param-value>http://www.testd.com:8080</param-value> </init-param> </filter> <!-- CAS Validation FILTER --> <filter> <filter-name>CAS Validation Filter</filter-name> <filter-class> org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter </filter-class> <!-- CAS SERVER URL --> <!-- https://www.test.com:8443/cas --> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>https://www.test.com:8443/cas</param-value> </init-param> <!-- LOCAL web URL --> <init-param> <param-name>serverName</param-name> <param-value>http://www.testd.com:8080</param-value> </init-param> <!-- if validation false throw exception ; default true--> <init-param> <param-name>exceptionOnValidationFailure</param-name> <param-value>false</param-value> </init-param> <!-- validation callback validate url --> <init-param> <param-name>proxyCallbackUrl</param-name> <param-value>http://www.teste.com:8080/teste</param-value> </init-param> <!-- proxyreceptor url --> <init-param> <param-name>proxyReceptorUrl</param-name> <param-value>/proxy/test.jsp</param-value> </init-param> </filter> <!-- cas security username on request.getRemoteUser() --> <filter> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <filter-class> org.jasig.cas.client.util.HttpServletRequestWrapperFilter </filter-class> </filter> <!-- CAS SINGLE SIGN OUT FILTER --> <filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class> org.jasig.cas.client.session.SingleSignOutFilter </filter-class> </filter> <filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Authentication Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <url-pattern>/index.jsp</url-pattern> </filter-mapping> <!-- SingleSignOutHttpSessionListener LISTENER --> <listener> <listener-class> org.jasig.cas.client.session.SingleSignOutHttpSessionListener </listener-class> </listener> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> 6 demo 部署及说明 拷贝demo目录下的文件到 相应的发布目录(tomcat/webapps)下,使用解压工具解压,打开对应demo的web.xml,将www.test.com 及 www.testd.com 、www.teste.com 修改为相应的路径 启动TOMCAT ,祝贺你CAS 部署成功了! 7 Cas 非HTTPS支持(不赞成使用) cas client 部分修改 打开edu.yale.its.tp.cas.client.filter类,注释此 if (!pv.isAuthenticationSuccesful()) // throw new ServletException( // "CAS authentication error: " + pv.getErrorCode() + ": " + pv.getErrorMessage()); Cas server 部分修改 打开 cas-server-webapp-3.3.1\WebRoot\WEB-INF\spring-configuration\ticketGrantingTicketCookieGenerator.xml 文件 将 p:cookieSecure="true" 值改为 p:cookieSecure="false" 备注:此文仅供参考,作者仅希望通过此文引导新手,相互交流,若有疑问或意见请与作者联系! 利剑 2008-12-16 QQ:349566018 E-mail:mygw@163.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值