轉自: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集成”這個現象,而是在解決這個現象的過程。在開發過程中,所有遇到的技術問題並不可怕,可怕的是你不知道如何去分析、分解問題,“大而化小,小而化了”才是解決問題的精髓。之所以說解決不了的問題,是因為你沒有掌握分析、解決問題所必要的基礎信息,比如“相關的領域知識”、涉及的技術特點。如果碰到了解決不了的問題,那肯定是在領域知識方面有欠缺,致使你不能分析、不能分解。
結論,在領域知識掌握到一定程度后,在領域范圍內,你就是專家。
