CAS 與.net 集成的 “循環重定向”問題分析


轉自:http://www.cnblogs.com/xingshao/archive/2011/09/29/2195746.html

 

近期的一個項目,項目包含了若干的子系統,因為人員配備的原因,項目會包含不同開發語言編寫〔java、.net〕的幾個子系統。項目從企業應用集成的角度進行架構,除了在應用層面上的“業務流程整合”之外。還有一個就是“身份認證”層面上的集成,身份認證的整合應用了CAS (Central Authentication Service),它是Yale 大學的 ITS 開發的一套 JAVA 實現的開源的SSO(single sign-on)的服務。

         Cas的部署、實現在java項目系統中都很順利的架設,實現了。但是在.net子系統中遇到了問題,.net下的集成是我今天要說的。

.net集成之初,參考了官上的范例(http://www.jasig.org/cas),它也提供.net客戶端的源碼下載。但是在調試的時候,出現了“循環請求驗證”的現象,Ie的現象是“一直登錄”,火狐下直接提示“循環訪問”一類的錯誤。

    首先在google直接找解決方法,但是遺憾的是並沒有直接解決類似問題的信息。有幾篇文章提到了這個現象,但是並沒有提出解決方案,msdn中有這個問題,但是回復者都是三言兩語,沒有詳細的解決方案,有的回答說“官網提供的是個半成品”。無語..暫且信之吧。

問題總是要解決的,以前沒有實際使用過這個東西,所以還是從頭開始吧,googel了一些cas的知識,對cas的機制,應用過程進行了解。

(具體知識詳見 http://linliangyi2007.iteye.com/blog/165310說的很通俗〕。

Cas .net版本的客戶端.是結合了asp.net自身的forms認證實現認證的。它是通過編寫一個httpModel進行攔截,通過對客戶端票據〔ticket〕的檢查來實現對每一次請求的過濾,進而達到對功能頁面的控制。首先在web.config中要配置一系列的cas服務端的參數信息,直接貼出

<configSections>

        <sectionname="casClientConfig"type="DotNetCasClient.Configuration.CasClientConfiguration, DotNetCasClient"/>

    </configSections>

 

 

    <casClientConfig

        casServerLoginUrl="http://192.168.12.196/cas/login"

        casServerUrlPrefix="http://192.168.12.196/cas"

        serverName="http://localhost:3273/ExampleWebSite"

        notAuthorizedUrl="~/NotAuthorized.aspx"

        cookiesRequiredUrl="~/CookiesRequired.aspx"

        redirectAfterValidation="true"

        gateway="false"

        renew="false"

        singleSignOut="true"

        ticketTimeTolerance="5000"

        ticketValidatorName="Cas20"

        serviceTicketManager="CacheServiceTicketManager"

        gatewayStatusCookieName="CasGatewayStatus" />

    <system.web>

 

.net 自己的Forms認證這的配置也很重要,

<authenticationmode="Forms">

            <forms

                loginUrl="http://192.168.12.196/cas/login"

                timeout="30"

                defaultUrl="~/Default.aspx"

                cookieless="UseCookies"

                slidingExpiration="true"

           path="/ExampleWebSite/"

               />    

        </authentication>

    <authorization>

      <denyusers="?"/>

      <allowusers="*"/>

    </authorization

 

最后就是httpModel的配置了

<httpModules>

      <addname="DotNetCasClient"type="DotNetCasClient.CasAuthenticationModule,DotNetCasClient"/>

    </httpModules>

 

 

    至此cas的基礎配置完成了,但是這是不夠的,這個的配置並沒有錯,但是實際運行中就會出現上述的“循環驗證”的問題,通過分析代碼,發現循環重定向到login頁面的原因是每一次的驗證都是失敗,票據丟失,會話狀態丟失。這個是引起循環重定向的直接凶手,

 

請求系統頁面-->httpModel重定向à cas登錄頁à登錄后的系統頁面àhttpModel驗證ticket失敗à重定向登錄cas

 

這個過程周而復始,那么問題的核心在那呢?.“httpModel驗證失敗”,這個是整個問題過程中的核心,通過調試,最終也確定了導致失敗的最終代碼段。

httpModel

 

CasAuthenticationTicket casTicket = null;

            FormsAuthenticationTicket formsAuthenticationTicket = GetFormsAuthenticationTicket();

            if (formsAuthenticationTicket != null)

            {

                ICasPrincipal principal;

                if (ServiceTicketManager != null)

                {

                    string serviceTicket = formsAuthenticationTicket.UserData;

                    casTicket = ServiceTicketManager.GetTicket(serviceTicket);

                    if (casTicket != null)

   

沒有發現票據,也就是說票據實失效引起的cas 認證的重定向登錄,那么是誰引起的ticket的失效呢?.最終排除了cas客戶端和服務端的問題,也就是說cas 配置是正確的,??那是什么引起最初的“循環重定向”現象呢。“Asp.net forms 驗證下的session失效”,問題由cas踢給.net自己的問題。最終問題再次轉移了,變成了“在.net下,session失效的問題”,但是也看到了曙光,因為這個問題googel一下.會有太多的信息供你瀏覽。同時,我發現我被“java 、cas”這樣的詞誤導了。基於.net的cas集成本身並不全是“cas”的問題,.net也是整合的一部分。

 

直接增加配置:

 

<sessionStatemode="StateServer"cookieless="UseCookies"timeout="36000"></sessionState>

 

1、啟用會話狀態,

2、開始asp.net狀態服務〔確保會話的持久,不在莫名其妙的失效。〕

3、對一些系統的頁面進行頁面緩存禁用,因為有幾次..緩存的頁面又一次誤導了,讓我以為cas的認證有問題。

 

通過解決asp.net的會話失效問題,發現應用cas后的“循環重定向”問題沒有了。

 

最后要說一下cas的“登出”操作,“登出”必須要.net forms登出和 cas的服務端登出結合。一定要先將服務端會話Abandon,然后在對cookie進行過期操作。最后清清除cas服務端的驗證票據。

 

FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(ticketCookie.Value);

                    if (CasAuthentication.ServiceTicketManager != null && ticket.UserData.Length > 0)

                    {

                        CasAuthenticationTicket casTicket = CasAuthentication.ServiceTicketManager.GetTicket(ticket.UserData);

                        CasAuthentication.ServiceTicketManager.RevokeTicket(casTicket.ServiceTicket);

                        CasAuthentication.ClearAuthCookie();

 

                        Session.Clear();

                        this.Session.Abandon();

                        Request.Cookies.Remove(FormsAuthentication.FormsCookieName);

                        Page.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);

 

                        CasAuthentication.SingleSignOut();

 

 

    至此,cas .net集成的問題徹底解決。本文強調的其實並不是解決“cas .net集成”這個現象,而是在解決這個現象的過程。在開發過程中,所有遇到的技術問題並不可怕,可怕的是你不知道如何去分析、分解問題,“大而化小,小而化了”才是解決問題的精髓。之所以說解決不了的問題,是因為你沒有掌握分析、解決問題所必要的基礎信息,比如“相關的領域知識”、涉及的技術特點。如果碰到了解決不了的問題,那肯定是在領域知識方面有欠缺,致使你不能分析、不能分解。

 

    結論,在領域知識掌握到一定程度后,在領域范圍內,你就是專家。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM