網站跨站點單點登錄實現--cookie


至於什么是單點登錄,舉個例子,如果你登錄了msn messenger,訪問hotmail郵件就不用在此登錄。
一般單點登錄都需要有一個獨立的登錄站點,一般具有獨立的域名,專門的進行注冊,登錄,注銷等操作

我們為了討論方便,把這個登錄站點叫做站點P,設其Url為http://passport.yizhu2000.com,需要提供服務的站點設為A和B,跨站點單點登錄是指你在A網站進行登錄后,使用B網站的服務就不需要再登錄


從技術角度講單點登錄分為:

  • 跨子域單點登錄
  • 完全跨單點域登錄

跨子域單點登錄

所謂跨子域登錄,A,B站點和P站點位於同一個域下面,比如A站點為http://blog.yizhu2000.com     B站點為 http://forum.yizhu2000.com,他們和登錄站點P的關系可以看到,都是屬於同一個父域,yizhu2000.com,不同的是子域不同,一個為blog,一個為forum,一個是passport

我們先看看最常用的非跨站點普通登錄的情況,一般登錄驗證通過后,一般會將你的用戶名和一些用戶信息,通過某一密鑰進行加密,寫在本地,也就是一個加密的cookie,我們把這個cookie叫做--票(ticket)。

需要判斷用戶是否登錄的頁面,需要讀取這個ticket,並從其中解密出用戶信息,如果ticket不存在,或者無法解密,意味着用戶沒有登錄,或者登錄信息不正確,這時就要跳轉到登錄頁面進行登錄,在這里加密的作用有兩個,一是防止用戶信息被不懷好意者看到,二是保證ticket不會被偽造,后者其實更為重要,加密后,各個應用需要采用與加密同樣的密鑰進行解密,如果不知道密鑰,就不能偽造出ticket,

(注:加密和解密的密鑰有可能不同,取決於采用什么加密算法,如果是對稱加密,則為同一密鑰,如果是非對稱,就不同了,一般用私鑰加密,公鑰解密,但是無論怎樣,密鑰都只有內部知道,這樣偽造者既無法偽造也無法解密ticket)

跨子域的單點登錄,和上述普通登錄的過程沒有什么不同,唯一不同的是寫cookie時,由於登錄站點P和應用A處於不同的子域,P站寫入的cookie的域為passport.yizhu2000.net,而A站點為forum.yizhu2000.net,A在判斷用戶登錄時無法讀到P站點的ticket

解決方法非常簡單,當Login完成后P站點寫ticket的時候,只需把cookie的域設為他們共同的父域,yizhu2000.net就可以了:cookie.domain="yizhu2000.net",A站點自然就可以讀到這個ticket了

ASP。Net的form驗證本身實現了這個機制,大家可以參考http://blog.csdn.net/octverve/archive/2007/09/22/1796338.aspx

ASP.NET身份驗證信息跨域共享狀態

在ASP.NET 2.0 中只需修改web.config文件即可,修改方法如下:

<authentication mode="Forms"> 
<forms name=".ASPNETFORM"   domain="imneio.com" loginUrl="/login.aspx" defaultUrl="/default.aspx" protection="All" timeout="30" path="/" requireSSL="false" slidingExpiration="true" enableCrossAppRedirects="false" cookieless="UseDeviceProfile" /> 
</authentication>

domain指定了cookie保存的域,只要保存的是 abc.com形式或者.abc.com的形式,那么其二級域名都可以共享此cookie。

此外,web.config標簽中的<sessionState >也做相應修改,mode改為StateServer或者SqlServer,那么里面的session信息也就全部可以共享了。

StateServer需要在服務中開啟“asp.net狀態服務”的服務

http://www.imneio.com/2007/11/17/aspnetnote1/,以上斜體內容摘自此鏈接

完全跨單點域登錄

完全跨域登錄,是指A,B站點和P站點沒有共同的父域,比如A站點為forum.yizhu1999.net,B站點為blog.yizhu1998.net,大家可以參考微軟旗下的幾個站點http://www.live.comwww.hotmail.com,這兩個站點就沒有共同的父域,而仍然可以共用登錄,怎樣才能實現呢?請參考下圖,由於這種情況ticket比較復雜,我們暫時把P站點創建的的ticket叫做P-ticket,而A站點創建的ticket叫A-ticket,B的為B-ticket

login

 

由於站點A(forum.yizhu1999.com)不能讀取到由站點P(passport.yizhu2000.com)創建的加密ticket,所以當用戶訪問A站點上需要登錄才能訪問的資源時,A站點會首先查看是否有A-ticket,如果沒有,證明用戶沒有在A站點登錄過,不過並不保證用戶沒有在B站點登錄,(重復一下,既然是單點登錄,當然無論你在A,B任意一個站點登錄過,另外一個站點都要可以訪問),請求會被重定向到p站點的驗證頁面,驗證頁面讀取P-ticket,如果沒有,或者解密不成功,就需要重定向登錄頁面,登錄頁面完成登錄后,寫一個加密cookie,也就是P-ticket,並且重定向到A站點的登錄處理頁,並把加密的用戶信息作為參數傳遞給這個頁面,這個頁面接收登錄頁的用戶信息,解密后也要寫一個cookie,也就是A-ticket,今后用戶再次訪問A站點上需要登錄權限才能訪問的資源時,只需要檢查這個A-cookie是否存在就可以了

當用戶訪問B站點時,會重復上面的過程,監測到沒有B-ticket,就會重定向到P站點的驗證頁面,去檢查P-ticket,如果沒有,就登錄,有則返回B的登錄處理頁面寫B-ticket

 

注銷的時候需要刪除P-ticket和A-ticket

 

logout

 

怎么刪除cookie:本來以為這個不是問題,不過還是有朋友問道,簡單的說其實是創建一個和你要刪除的cookie同名的cookie,並把cookie的expire設為當前時間之前的某個時間,不過在跨子域的刪除cookie時有一點要注意:必須要把cookie的域設置為父域,在本文中為yizhu2000.com

為了保證各個環節的傳輸的安全性,最好使用https連接


免責聲明!

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



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