acegi整合CAS (sso)

acegi內置了對CAS的支持。這裏的CAS是3.0。建立CAS server是一個比較簡單的事情。CAS server就是一個標準的war文件,把它發佈就可以運行。需要做的僅僅是調整登陸和其他一些頁面。先了解一下CAS如何實現SSO。
例子:原有系統A和系統B,現在在它們之間做SSO。
很顯然,系統A和B都是CAS client。首先是訪問系統A,幹掉A的登陸頁面,在A的入口判斷有沒有Ticket(票據),如果沒有則重定向到CAS server,在CAS server提供Credential(大多數情況就是用戶名和密碼)。CAS server的作用非常簡單:就是來驗證用戶密碼。正確,則發送Ticket。CAS有5種Ticket,分別是TGC(通過cookie發送的ticket),ST(Service Ticket),PGT,PGTIOU,PT。其中PGT,PGTIOU,PT屬於代理ticket,這裏不作討論。具體可以參考
http://www.blogjava.net/openssl/archive/2006/04/26/SSO_CASProxy.html
TGC和ST的關係可以打個比方:
我去中央電視塔去玩,結果發現地下還有個海底世界。SSO前我是這麼玩的:先去電視塔買張門票,玩完了;再去海底世界買張門票,玩完了。發現真累,兩個景點這麼近還要買兩次門票,就不能搞個通票嗎?於是就SSO。於是這樣:我先去電視塔,門衛告訴我你不能進去要買票,於是把我送到通票售票處(CAS server)買票(登錄),買吧,於是給了我兩張票,注意,是兩張,一張發到我手裏,上面寫着僅限電視塔使用(ST);靠,不是通票嗎,咋僅限電視塔使用?別急,還有一張票(TGC)通過cookie發送你看不見。人家說了保證沒問題,我咋辦,這是人家的規矩,那就先去玩吧。出了電視塔我直撲海底世界,
門衛說要海底世界票,不會吧,我買的通票啊,門衛說不着急,又把我送回通票售票處(CAS server),通票售票處(CAS server)一看,發現我有TGC,嘿嘿,這傢伙買過票了不用再買(不用再登錄),於是換我一張票(ST)上面寫着僅限海底世界使用,於是我就拿着這張票又去海底世界了。於是我明白了啥是SSO了,不就是把買票改成換票了嗎?
比方完了,最開始的例子也就不往下繼續了。需要注意的是系統A和B整合SSO需要把A、B的用戶密碼集中管理,你說A中我的用戶名是張三,B中是李四,SSO能不能幫我自動識別,回答是不行的。
繼續Acegi的整合。
CAS server是做用戶密碼驗證,具體的權限授權的工作還是在各個單個系統裏,也不應該交給它管。做用戶密碼驗證需要AuthenticationHandler。這個具體就是根據Credential返回一個boolean值來判斷你輸入的用戶密碼正不正確。acegi提供了一個實現。
以一個典型的web訪問來說明整個過程
1、用戶訪問一個受acegi安全保護的頁面或業務方法;
2、用戶沒有登陸的話顯然會拋出AuthenticationException
3、配置exceptionTranslationFilter捕獲這個異常重定向到CAS server登陸頁面
       <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重定向回來的頁面
  https://my.company.com/cas/login?service=https%3A%2F%2Fserver.company.com%2Fmyapp%2Fj_acegi_cas_security_check
4、CAS server檢查是否有TGC ,沒有則登陸,登陸後返回。這裏屁股後面跟着的即ST,TGC通過cookie一併發送到客戶端。
   https://server.company.com/myapp/j_acegi_cas_security_check?ticket=ST-0-jhsdfguwgeds
5、配置casProcessingFilter來處理返回ST(和以前的authenticationProcessingFilter比較類似)
   <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通過 casProxyTicketValidator來校驗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又具體實現調用了CAS Client library裏的ProxyTicketValidator校驗ST,ProxyTicketValidator 就比較有意思了,它做了個HTTPS請求CAS server,結果還是CAS server來校驗ST(繞了一大圈)
 https://my.company.com/cas/proxyValidate?service=https%3A%2F%2Fserver.company.com%2Fmyapp%2Fj_acegi_cas_security_check
 重新回到CAS server,它接受到這個HTTPS請求,檢查ST是否與對這個service發行的ST吻合,吻合的話CAS server就會發回一個肯定的XML回覆,裏面包含了用戶名(username)。剩下的就EASY了,casProxyTicketValidator解析XML,casProxyDecider處理代理,casAuthoritiesPopulator根據解析後的XML獲得user,最後就是casAuthenticationProvider構造Authentication(這裏是CasAuthenticationToken)
7、重新回到casProcessingFilter,它將Authentication放入HttpSession
這樣就完成了整個過程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章