由于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了。