由于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),服务票据
等概念不理解,建议请阅读中篇的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能够正常被加载(默认配置即可)。
<
servlet
>
<
servlet-name
>
proxy
servlet-name
>
<
servlet-class
>
edu.yale.its.tp.cas.servlet.proxy
servlet-class
>
servlet
>
<
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了。