ASP.NET跨應用程序進行登錄的解決 (摘)

最近一個朋友問我一個問題:

       如何可以將ASPdotNET Forum2.0放到他的一個項目中(好象網上也有人討論過如何將dotText和ASPdotNET Forum等開源項目集成起來的),他原來的項目已經有一套用戶登錄機制了,而且用戶數據庫也是現成的,如何使得在他原來系統上登錄後就可以直接轉到Forum上,而又不需要再次輸入用戶信息呢?剛開始感覺a piece of cake...象這種一次登錄,然後可以訪問多個應用其實在很久就已經提出來了,在幾年前還幫公司做過一個類似的產品原型,但那個是針對異構網站的,說白了就是做一個代理,只是內部有套機制將後面的幾個異構網站的用戶數據庫映射起來而已。這種方式看起來似乎可以解決問題,但數據庫之間的映射關係處理起來很麻煩,如果下面應用多了的話,工作量是很大的。

        對於這種技術,似乎有個名詞叫Single Sign On,有點象網易的通行證了。如果內部網站是同一批人做的倒問題不大,只要協調好了這個通行證的格式和一些相關的問題就可以了。而朋友的情況似乎也沒有那麼複雜,他原來的項目也是用.NET平臺技術的。.NET平臺下是否有比較好的整合解決方案呢?


這自然涉及到了.NET平臺下驗證的相關問題了。ASP.NET自身已經支持三種驗證方式(不包括None):
1. Windows身份驗證,新建立一個Web應用,似乎缺省就是用這樣的方式的。顯然這個不是需要的。
2. Passprot身份驗證,需要Microsoft支持,它其實提供了一個WebServices來幫助你統一完成驗證工作,使   用這個在內部 網項目中似乎沒有太大必要。
3. Forms身份驗證,通過Cookie來傳遞身份驗證信息,看起來類似通行證之類的,應該是要找的東西了。

圖是Forms身份驗證的數據流程圖(MSDN中的)

       上圖十分清晰的描述了Forms身份驗證的基本原理,但是對於多個應用呢?仔細查MSDN(MSDN真的好多資料啊,經常看過了再想翻回去已經忘記在那裏找出來的了   BTW:有沒有MSDN書籤功能的?),發現相關的描述很多,但只有一個“跨應用程序進行Forms 身份驗證”比較具體,而內容就簡單些了。

看來還是需要自己先動手做個簡單的測試來邊試邊查資料了...



先建立一個testLogon的Web應用
主要文件包括:
default.aspx (通過驗證跳入的頁面)
test1.apsx   (登錄的頁面)
Global.asax 
Web.config   (配置文件)

再建立另外一個testLogon2的Web應用
主要文件:
default.aspx (通過驗證跳入的頁面)
Global.asax
Web.config    (配置文件)



測試最終達到的效果:
兩個Web應用的default都是受保護的,沒有通過驗證是不可以進入的,即使在輸入訪問地址URL,會自動跳轉到testLogon/test1.aspx要求登錄,當登錄通過後,則可以任意在兩個應用的default.aspx跳轉。
testLogon/default.aspx中有Logout的功能,Logout後則需要重新登錄了。

要達到這個效果,基本設置需要:
1.將IIS配置爲允許匿名訪問,保證可以通過IIS來控制傳遞請求給ASP.NET;
2.如果必要傳輸過程配置爲SSL,這裏沒有這個必要了;
3.對應的兩個應用的配置文件必須設成一致;

以上這些基本設置在MSDN中都可以找到相關的描述,但是實驗這個效果到成功卻花費了比預計長的時間,因此覺得十分有必要將其記錄下來,對自己對他人都有好處。

得到的經驗教訓如下:
1.配置文件Web.config中,將驗證模式設爲Forms,而且在下面的參數中,要保證兩邊一致
testLogon的Web.config對應部分

    <authentication mode="Forms">
    
<forms name=".AspNetForums" protection="Encryption" timeout="60" loginUrl="test1.aspx" />
    
</authentication>

testLogon2的Web.config對應部分

    <authentication mode="Forms">
       
<forms name=".AspNetForums" protection="Encryption" timeout="60" loginUrl="/testLogon/test1.aspx" />
    
</authentication>


2.<machineKey>的增加是必須的
爲保證兩邊兩邊應用對cookie的處理和讀取一致,這個屬性是必須的,且要相同

     <machineKey
         
validationKey= "C50B3C89CB21F4F1422FF158A5B42D0E8DB8CB5CDA1742572A487D9401E3400267682B202B746511891C1BAF47F8D25C07F6C39A104696DB51F17C529AD3CABE" 
         decryptionKey
= "8A9BE8FD67AF6979E7D20198CFEA50DD3D3799C77AF2B72F" 
         validation
="SHA1"> 
     
</machineKey>



3.MSDN雖然要查,但不可以完全依靠,特別是代碼
在MSDN中,關於machineKey的代碼如下:

<configuration>
    
<system.web>
        
<authentication>
            
<forms name=".ASPXAUTH" 
                   loginUrl
="logon.aspx"     
                   protection
="all"  <!-- Protection must be identical.-->
                   timeout="30" 
                   path="/" >   
<!-- Path must have a compatible scope.-->
        
</authentication>

        
<!-- Validation and decryption keys must exactly match and cannot
             be set to "AutoGenerate". The validation algorithm must also 
             be the same. 
-->
        
<machineKey>
            validationKey= "C50B3C89CB21F4F1422FF158A5B42D0E8DB8CB5CDA1742572A487D9401E3400267682B202B746511891C1BAF47F8D25C07F6C39A104696DB51F17C529AD3CABE" 
            decryptionKey= "8A9BE8FD67AF6979E7D20198CFEA50DD3D3799C77AF2B72F" 
            validation="SHA1"
            isolateApplications="false"
        
</machineKey>
    
</system.web>
</configuration>

 

但顯然有着錯誤的,大家編譯一下就知道了,格式錯了,而且isolateApplication也不是這樣用的

4.爲保證兩邊讀到的cookie一致,不要用isolateApplication,它使得各自用自己的cookie了。

5.關於Global.asax的注意,對於Web.config中authentication的節點會觸發Global.asax中的事件的,對應

函數是

protected void Application_AuthenticateRequest(Object sender, EventArgs e)


6.研究一下ASPdotNetForum2.0代碼發現,Global.asax不見了,而在它的配置文件中多了一項

        <httpModules>
            
<add name="AspNetForums" type="AspNetForums.ForumsHttpModule, AspNetForums.Components" />
        
</httpModules>


是的,看一下ForumsHttpModule的源碼,結構和Global.asax基本一樣,一樣有個事件觸發函數

 private void Application_AuthenticateRequest(Object source, EventArgs e) 



       下面不用我多說了吧?具體該如何做到和dotNetForum一起達到SSO的目標的答案已經出來了

例子代碼下載

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