現在很多大的互聯網公司都會有很多的應用,比如以下是淘寶網的截圖:
天貓 聚劃算 頭條等都是不同的應用,有的甚至采用完全不同的域名,但是所有在淘寶注冊的用戶都是使用的一套用戶名和口令,如果在這些系統直接切換做不到登陸狀態的同 步,體驗是非常差的。再舉個栗子,很多公司內部系統也有很多個,比如HR系統,財務系統,考勤系統等等,如果員工在一個系統登陸了,跳轉到另外一個系統還 需要登陸,就會讓人很不爽...
基於此,SSO(Single Sign On)
應運而生。當然,我們來現實這個需求的方法有很多種,使用Cookie是其中比較簡單的方式,主要需要解決的問題是:Cookie
是不能跨域傳遞的,如何將一個域的Cookie
通知給其它應用(不在同一個域)?
so
,如果你對cookie
機制不太熟悉,請先google
,並大致了解為什麼cookie
會設計成不能跨域等相關問題。
SSO有以下幾種方式實現
當我們的子系統都在一個父級域名下時,我們可以將Cookie種在父域下,這樣浏覽器同域名下的Cookie則可以共享,這樣可以通過Cookie加解密的算法獲取用戶SessionID,從而實現SSO。
但是,後面我們發現這種方式有幾種弊端:
a. 所有同域名的系統都能獲取SessionID,易被修改且不安全;
b. 跨域無法使用。
這種實現的SSO有以下幾個步驟:
a. 用戶訪問某個子系統,發現如果未登錄,則引導用戶跳轉到SSO登錄頁面;
b. 判斷SSO是否已經登錄;
c. 如果已經登錄,直接跳轉到回調地址,並返回認證ticket;
d. 如果未登錄,用戶正確輸入用戶名/密碼,認證通過跳轉到回調地址,並返回認證ticket;
e. 子系統獲取ticket,調用SSO獲取用戶uid等信息,成功後讓用戶登錄。
前面已經說了,如何通過Cookie
來實現SSO
,主要是如何解決跨域問題。首先來談談Set-Cookie
中的domain
屬性。
為了讓Http
協議在一定程度上保持上下文,server
在響應的頭部可以加入Set-Cookie
來寫入一些數據到客戶端,Set-Cookie
中的domain
字段用來表示這個cookie
所在的域。
栗子:
我們訪問www.cookieexm.com
,如果server
在返回頭部中加入了Set-Cookie
,如果不指定domain
,那麼默認這個cookie
的域就是www.cookieexm.com
,也就是只有訪問www.cookieexm.com
時客戶端才會把這個cookie
返給服務端。
如果我們指定domain
為.cookieexm.com
,那麼客戶端在訪問以下域名:www.cookieexm.com www1.cookieexm.com a.cookieexm.com ***.cookieexm.com
時都能夠把cookie
返回。
所以,我們得出一條結論:客戶端對cookie的domain的匹配是從結尾進行匹配的,有了這個基礎,我們就可以實現我們的SSO
登陸了。
cookie中需要注意的
假設我們需要在如下子系統 **.a1.a2 **.b1.b2 **.c1.c2
間實現單點登錄,首先我們需要一個專門用於單點登陸的認證系統(sso.s1.s2)。假設目前系統處於未登錄狀態,訪問www.a1.a2
為例:
分別看一下每個步驟作用:
說明:
業務認證系統不一定存在,有些不是太敏感的系統可以直接從SSO Authorization
重定向到業務系統,並把SSO
的認證信息帶過去。
承接上文,此時,如果用戶訪問www.b1.b2
應用,如下圖所示:
與訪問www.a1.a2
不同的是我們在重定向到SSO Authorization
時已經不需要再去輸入用戶名,因為sso.s1.s2
此時已經存有cookie
,直接用cookie
驗證。
以上,就是一個簡單的基於Cookie
的登陸系統。
對於第一個問題,一般可以采用類似與memcached的分布式緩存的方案,既能提供可擴展數據量的機制,也能提供高效訪問
對於第二個問題,一般采取數字簽名的方法,要麼通過數字證書簽名,要麼通過像md5的方式,這就需要SSO系統返回免登URL的時候對需驗證的參數進行 md5加密,並帶上token一起返回,最後需免登的系統進行驗證信任關系的時候,需把這個token傳給SSO系統,SSO系統通過對token的驗證 就可以辨別信息是否被改過
對於最後一個問題,可以通過白名單來處理,說簡單點只有在白名單上的系統才能請求生產信任關系,同理只有在白名單上的系統才能被免登錄。
轉載地址:http://www.jianshu.com/p/baa94d5f1673