昨天和幾位朋友探討到了這個話題,發現雖然單點登陸,或者叫作獨立的passport登陸雖然已經有了不少實現方法,可是能真正瞭解並實現的人卻並不太多,因此些下此文,但願從原理到實現,能讓你們瞭解的多一些html
至於什麼是單點登陸,舉個例子,若是你登陸了msn messenger,訪問hotmail郵件就不用在此登陸。
通常單點登陸都須要有一個獨立的登陸站點,通常具備獨立的域名,專門的進行註冊,登陸,註銷等操做web
咱們爲了討論方便,把這個登陸站點叫作站點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)。cookie
須要判斷用戶是否登陸的頁面,須要讀取這個ticket,並從其中解密出用戶信息,若是ticket不存在,或者沒法解密,意味着用戶沒有登陸,或者登陸信息不正確,這時就要跳轉到登陸頁面進行登陸,在這裏加密的做用有兩個,一是防止用戶信息被不懷好意者看到,二是保證ticket不會被僞造,後者其實更爲重要,加密後,各個應用須要採用與加密一樣的密鑰進行解密,若是不知道密鑰,就不能僞造出ticket,session
(注:加密和解密的密鑰有可能不一樣,取決於採用什麼加密算法,若是是對稱加密,則爲同一密鑰,若是是非對稱,就不一樣了,通常用私鑰加密,公鑰解密,可是不管怎樣,密鑰都只有內部知道,這樣僞造者既沒法僞造也沒法解密ticket)asp.net
跨子域的單點登陸,和上述普通登陸的過程沒有什麼不一樣,惟一不一樣的是寫cookie時,因爲登陸站點P和應用A處於不一樣的子域,P站寫入的cookie的域爲passport.yizhu2000.net,而A站點爲forum.yizhu2000.net,A在判斷用戶登陸時沒法讀到P站點的ticketless
解決方法很是簡單,當Login完成後P站點寫ticket的時候,只需把cookie的域設爲他們共同的父域,yizhu2000.net就能夠了:cookie.domain="yizhu2000.net",A站點天然就能夠讀到這個ticket了dom
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.com,www.hotmail.com,這兩個站點就沒有共同的父域,而仍然能夠共用登陸,怎樣才能實現呢?請參考下圖,因爲這種狀況ticket比較複雜,咱們暫時把P站點建立的的ticket叫作P-ticket,而A站點建立的ticket叫A-ticket,B的爲B-ticket
因爲站點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
怎麼刪除cookie:原本覺得這個不是問題,不過仍是有朋友問道,簡單的說實際上是建立一個和你要刪除的cookie同名的cookie,並把cookie的expire設爲當前時間以前的某個時間,不過在跨子域的刪除cookie時有一點要注意:必需要把cookie的域設置爲父域,在本文中爲yizhu2000.com
爲了保證各個環節的傳輸的安全性,最好使用https鏈接