acegi內(nèi)置了對(duì)CAS的支持。這里的CAS是3.0。建立CAS server是一個(gè)比較簡(jiǎn)單的事情。CAS server就是一個(gè)標(biāo)準(zhǔn)的war文件,把它發(fā)布就可以運(yùn)行。需要做的僅僅是調(diào)整登陸和其他一些頁(yè)面。先了解一下CAS如何實(shí)現(xiàn)SSO。
例子:原有系統(tǒng)A和系統(tǒng)B,現(xiàn)在在它們之間做SSO。
很顯然,系統(tǒng)A和B都是CAS client。首先是訪問(wèn)系統(tǒng)A,干掉A的登陸頁(yè)面,在A的入口判斷有沒(méi)有Ticket(票據(jù)),如果沒(méi)有則重定向到CAS server,在CAS server提供Credential(大多數(shù)情況就是用戶名和密碼)。CAS server的作用非常簡(jiǎn)單:就是來(lái)驗(yàn)證用戶密碼。正確,則發(fā)送Ticket。CAS有5種Ticket,分別是TGC(通過(guò)cookie發(fā)送的ticket),ST(Service Ticket),PGT,PGTIOU,PT。其中PGT,PGTIOU,PT屬于代理ticket,這里不作討論。具體可以參考
http://www.aygfsteel.com/openssl/archive/2006/04/26/SSO_CASProxy.htmlTGC和ST的關(guān)系可以打個(gè)比方:
我去中央電視塔去玩,結(jié)果發(fā)現(xiàn)地下還有個(gè)海底世界。SSO前我是這么玩的:先去電視塔買(mǎi)張門(mén)票,玩完了;再去海底世界買(mǎi)張門(mén)票,玩完了。發(fā)現(xiàn)真累,兩個(gè)景點(diǎn)這么近還要買(mǎi)兩次門(mén)票,就不能搞個(gè)通票嗎?于是就SSO。于是這樣:我先去電視塔,門(mén)衛(wèi)告訴我你不能進(jìn)去要買(mǎi)票,于是把我送到通票售票處(CAS server)買(mǎi)票(登錄),買(mǎi)吧,于是給了我兩張票,注意,是兩張,一張發(fā)到我手里,上面寫(xiě)著僅限電視塔使用(ST);靠,不是通票嗎,咋僅限電視塔使用?別急,還有一張票(TGC)通過(guò)cookie發(fā)送你看不見(jiàn)。人家說(shuō)了保證沒(méi)問(wèn)題,我咋辦,這是人家的規(guī)矩,那就先去玩吧。出了電視塔我直撲海底世界,
門(mén)衛(wèi)說(shuō)要海底世界票,不會(huì)吧,我買(mǎi)的通票啊,門(mén)衛(wèi)說(shuō)不著急,又把我送回通票售票處(CAS server),通票售票處(CAS server)一看,發(fā)現(xiàn)我有TGC,嘿嘿,這家伙買(mǎi)過(guò)票了不用再買(mǎi)(不用再登錄),于是換我一張票(ST)上面寫(xiě)著僅限海底世界使用,于是我就拿著這張票又去海底世界了。于是我明白了啥是SSO了,不就是把買(mǎi)票改成換票了嗎?
比方完了,最開(kāi)始的例子也就不往下繼續(xù)了。需要注意的是系統(tǒng)A和B整合SSO需要把A、B的用戶密碼集中管理,你說(shuō)A中我的用戶名是張三,B中是李四,SSO能不能幫我自動(dòng)識(shí)別,回答是不行的。
繼續(xù)Acegi的整合。
CAS server是做用戶密碼驗(yàn)證,具體的權(quán)限授權(quán)的工作還是在各個(gè)單個(gè)系統(tǒng)里,也不應(yīng)該交給它管。做用戶密碼驗(yàn)證需要AuthenticationHandler。這個(gè)具體就是根據(jù)Credential返回一個(gè)boolean值來(lái)判斷你輸入的用戶密碼正不正確。acegi提供了一個(gè)實(shí)現(xiàn)。
以一個(gè)典型的web訪問(wèn)來(lái)說(shuō)明整個(gè)過(guò)程
1、用戶訪問(wèn)一個(gè)受acegi安全保護(hù)的頁(yè)面或業(yè)務(wù)方法;
2、用戶沒(méi)有登陸的話顯然會(huì)拋出AuthenticationException
3、配置exceptionTranslationFilter捕獲這個(gè)異常重定向到CAS server登陸頁(yè)面
???????<bean?id="exceptionTranslationFilter"?class="org.acegisecurity.ui.ExceptionTranslationFilter">
????????????<property?name="authenticationEntryPoint"><ref?local="casProcessingFilterEntryPoint"/></property>
????????</bean>
????????
????????<bean?id="casProcessingFilterEntryPoint"?class="org.acegisecurity.ui.cas.CasProcessingFilterEntryPoint">
????????????<property?name="loginUrl"><value>https://my.company.com/cas/login</value></property>
????????????<property?name="serviceProperties"><ref?local="serviceProperties"/></property>
????????</bean>
????????
????????<bean?id="serviceProperties"?class="org.acegisecurity.ui.cas.ServiceProperties">
????????????<property?name="service"><value>https://server.company.com/myapp/j_acegi_cas_security_check</value></property>
????????????<property?name="sendRenew"><value>false</value></property>
????????</bean>serviceProperties里的service屬性即在CAS server登陸完畢后由CAS server重定向回來(lái)的頁(yè)面
??
https://my.company.com/cas/login?service=https%3A%2F%2Fserver.company.com%2Fmyapp%2Fj_acegi_cas_security_check4、CAS server檢查是否有TGC ,沒(méi)有則登陸,登陸后返回。這里屁股后面跟著的即ST,TGC通過(guò)cookie一并發(fā)送到客戶端。
??
https://server.company.com/myapp/j_acegi_cas_security_check?ticket=ST-0-jhsdfguwgeds5、配置casProcessingFilter來(lái)處理返回ST(和以前的authenticationProcessingFilter比較類(lèi)似)
???<bean?id="casProcessingFilter"?class="org.acegisecurity.ui.cas.CasProcessingFilter">
????????<property?name="authenticationManager"><ref?local="authenticationManager"/></property>
????????<property?name="authenticationFailureUrl"><value>/casfailed.jsp</value></property>
????????<property?name="defaultTargetUrl"><value>/</value></property>
????????<property?name="filterProcessesUrl"><value>/j_acegi_cas_security_check</value></property>
????</bean>6、配置authenticationManager
???<bean?id="authenticationManager"?class="org.acegisecurity.providers.ProviderManager">
??????<property?name="providers">
?????????<list>
????????????<ref?local="casAuthenticationProvider"/>
?????????</list>
??????</property>
???</bean>
???
??<bean?id="casAuthenticationProvider"?class="org.acegisecurity.providers.cas.CasAuthenticationProvider">
????????<property?name="casAuthoritiesPopulator"><ref?local="casAuthoritiesPopulator"/></property>
????????<property?name="casProxyDecider"><ref?local="casProxyDecider"/></property>
????????<property?name="ticketValidator"><ref?local="casProxyTicketValidator"/></property>
????????<property?name="statelessTicketCache"><ref?local="statelessTicketCache"/></property>
????????<property?name="key"><value>my_password_for_this_auth_provider_only</value></property>
????</bean>?具體作用的是casAuthenticationProvider,casAuthenticationProvider通過(guò) casProxyTicketValidator來(lái)校驗(yàn)ST
????<bean?id="casProxyTicketValidator"?class="org.acegisecurity.providers.cas.ticketvalidator.CasProxyTicketValidator">
????????<property?name="casValidate"><value>https://my.company.com/cas/proxyValidate</value></property>
????????<property?name="serviceProperties"><ref?local="serviceProperties"/></property>
????</bean>?casProxyTicketValidator又具體實(shí)現(xiàn)調(diào)用了CAS Client library里的ProxyTicketValidator校驗(yàn)ST,ProxyTicketValidator?就比較有意思了,它做了個(gè)HTTPS請(qǐng)求CAS server,結(jié)果還是CAS server來(lái)校驗(yàn)ST(繞了一大圈)
?
https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver.company.com%2Fmyapp%2Fj_acegi_cas_security_check?重新回到CAS server,它接受到這個(gè)HTTPS請(qǐng)求,檢查ST是否與對(duì)這個(gè)service發(fā)行的ST吻合,吻合的話CAS server就會(huì)發(fā)回一個(gè)肯定的XML回復(fù),里面包含了用戶名(username)。剩下的就EASY了,casProxyTicketValidator解析XML,casProxyDecider處理代理,casAuthoritiesPopulator根據(jù)解析后的XML獲得user,最后就是casAuthenticationProvider構(gòu)造Authentication(這里是CasAuthenticationToken)
7、重新回到casProcessingFilter,它將Authentication放入HttpSession
這樣就完成了整個(gè)過(guò)程
http://www.aygfsteel.com/ronghao 榮浩原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處:)
posted on 2006-08-29 12:31
ronghao 閱讀(6269)
評(píng)論(5) 編輯 收藏 所屬分類(lèi):
權(quán)限相關(guān)