PHP中SSO Cookie登錄分析和實現(xiàn)
什么是SSO?
單點登錄SSO(Single Sign-On)是身份管理中的一部分。SSO的一種較為通俗的定義是:SSO是指訪問同一服務器不同應用中的受保護資源的同一用戶,只需要登錄一次,即通過一個應用中的安全驗證后,再訪問其他應用中的受保護資源時,不再需要重新登錄驗證
SSO的用途:
目前的企業(yè)應用環(huán)境中,往往有很多的應用系統(tǒng),淘寶、天貓、愛淘寶等等產品和如辦公自動化(OA)系統(tǒng),財務管理系統(tǒng),檔案管理系統(tǒng),信息查詢系統(tǒng)等等。這些應用系統(tǒng)服務于企業(yè)的信息化建設,為企業(yè)帶來了很好的效益。但是,用戶在使用這些應用系統(tǒng)時,并不方便。用戶每次使用系統(tǒng),都必須輸入用戶名稱和用戶密碼,進行身份驗證;而且應用系統(tǒng)不同,用戶賬號就不同,用戶必須同時牢記多套用戶名稱和用戶密碼。特別是對于應用系統(tǒng)數(shù)目較多,用戶數(shù)目也很多的企業(yè),這個問題尤為突出。問題的原因并不是系統(tǒng)開發(fā)出現(xiàn)失誤,而是缺少整體規(guī)劃,缺乏統(tǒng)一的用戶登錄平臺,使用SSO技術可以解決以上這些問題
SSO的好處:
方便用戶:從用戶實際使用角度考慮
用戶使用應用系統(tǒng)時,能夠一次登錄,多次使用。用戶不再需要每次輸入用戶名稱和用戶密碼,也不需要牢記多套用戶名稱和用戶密碼。單點登錄平臺能夠改善用戶使用應用系統(tǒng)的體驗。
方便管理員:從日常維護管理角度考慮
現(xiàn)在很多大的互聯(lián)網(wǎng)公司都會有很多的應用,比如以下是淘寶網(wǎng)的截圖:
天貓 聚劃算 頭條等都是不同的應用,有的甚至采用完全不同的域名,但是所有在淘寶注冊的用戶都是使用的一套用戶名和口令,如果在這些系統(tǒng)直接切換做不到登陸狀態(tài)的同 步,體驗是非常差的。再舉個栗子,很多公司內部系統(tǒng)也有很多個,比如HR系統(tǒng),財務系統(tǒng),考勤系統(tǒng)等等,如果員工在一個系統(tǒng)登陸了,跳轉到另外一個系統(tǒng)還 需要登陸,就會讓人很不爽...
基于此,SSO(Single Sign On)應運而生。當然,我們來現(xiàn)實這個需求的方法有很多種,使用Cookie是其中比較簡單的方式,主要需要解決的問題是:Cookie是不能跨域傳遞的,如何將一個域的Cookie通知給其它應用(不在同一個域)?
so,如果你對cookie機制不太熟悉,請先google,并大致了解為什么cookie會設計成不能跨域等相關問題。
系統(tǒng)管理員只需要維護一套統(tǒng)一的用戶賬號,方便、簡單。相比之下,系統(tǒng)管理員以前需要管理很多套的用戶賬號。每一個應用系統(tǒng)就有一套用戶賬號,不僅給管理上帶來不方便,而且,也容易出現(xiàn)管理漏洞。
簡化應用系統(tǒng)開發(fā):從應用擴展角度考慮
開發(fā)新的應用系統(tǒng)時,可以直接使用單點登錄平臺的用戶認證服務,簡化開發(fā)流程。單點登錄平臺通過提供統(tǒng)一的認證平臺,實現(xiàn)單點登錄。因此,應用系統(tǒng)并不需要開發(fā)用戶認證程序。
如何實現(xiàn)?
SSO有以下幾種方式實現(xiàn)
共享Cookie
當我們的子系統(tǒng)都在一個父級域名下時,我們可以將Cookie種在父域下,這樣瀏覽器同域名下的Cookie則可以共享,這樣可以通過Cookie加解密的算法獲取用戶SessionID,從而實現(xiàn)SSO。
但是,后面我們發(fā)現(xiàn)這種方式有幾種弊端:
a. 所有同域名的系統(tǒng)都能獲取SessionID,易被修改且不安全;
b. 跨域無法使用。
ticket驗證,我們目前采取的是這種方式
這種實現(xiàn)的SSO有以下幾個步驟:
a. 用戶訪問某個子系統(tǒng),發(fā)現(xiàn)如果未登錄,則引導用戶跳轉到SSO登錄頁面;
b. 判斷SSO是否已經登錄;
c. 如果已經登錄,直接跳轉到回調地址,并返回認證ticket;
d. 如果未登錄,用戶正確輸入用戶名/密碼,認證通過跳轉到回調地址,并返回認證ticket;
e. 子系統(tǒng)獲取ticket,調用SSO獲取用戶uid等信息,成功后讓用戶登錄。
前面已經說了,如何通過Cookie來實現(xiàn)SSO,主要是如何解決跨域問題。首先來談談Set-Cookie中的domain屬性。
Cookie domain
為了讓Http協(xié)議在一定程度上保持上下文,server在響應的頭部可以加入Set-Cookie來寫入一些數(shù)據(jù)到客戶端,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的匹配是從結尾進行匹配的,有了這個基礎,我們就可以實現(xiàn)我們的SSO登陸了。
cookie中需要注意的
設置為http-only
涉及登錄憑證(如票據(jù)或者用戶名)應該加密
cookie不能存放隱私數(shù)據(jù)
具體方案
假設我們需要在如下子系統(tǒng) **.a1.a2 **.b1.b2 **.c1.c2間實現(xiàn)單點登錄,首先我們需要一個專門用于單點登陸的認證系統(tǒng)(sso.s1.s2)。假設目前系統(tǒng)處于未登錄狀態(tài),訪問www.a1.a2為例:
分別看一下每個步驟作用:
www.a1.a2收到請求,檢查是否攜帶登錄的cookie,目前沒有登陸過,那么重定向到sso認證中心
SSO提供登陸窗口,用戶輸入用戶名 口令。SSO系統(tǒng)驗證用戶名和口令
這一步是關鍵,如果登錄成功,首先把SSO系統(tǒng)的Cookie放到客戶端;同時,將用戶的認證信息傳遞通過重定向傳遞給業(yè)務方,注意,這個傳遞明顯不能通過cookie來傳遞(不同域嘛),一般是通過加密的querystring。
業(yè)務方的驗證系統(tǒng)收到sso認證信息,再進行認證
業(yè)務方認證通過之后,把認證結果的cookie寫入到.a1.a2,至此,SSO認證完成
重定向到業(yè)務系統(tǒng)www.a1.a2,由前面的結論可知,此時所有以.a1.a2結尾的業(yè)務系統(tǒng)都可以使用這個認證之后的cookie
response
說明:
業(yè)務認證系統(tǒng)不一定存在,有些不是太敏感的系統(tǒng)可以直接從SSO Authorization重定向到業(yè)務系統(tǒng),并把SSO的認證信息帶過去。
承接上文,此時,如果用戶訪問www.b1.b2應用,如下圖所示:
與訪問www.a1.a2不同的是我們在重定向到SSO Authorization時已經不需要再去輸入用戶名,因為sso.s1.s2此時已經存有cookie,直接用cookie驗證。
以上,就是一個簡單的基于Cookie的登陸系統(tǒng)。
其中幾個問題需要重點解決
如何高效存儲大量臨時性的信任數(shù)據(jù)
如何防止信息傳遞過程被篡改
如何讓SSO系統(tǒng)信任登錄系統(tǒng)和免登系統(tǒng)
對于第一個問題,一般可以采用類似與memcached的分布式緩存的方案,既能提供可擴展數(shù)據(jù)量的機制,也能提供高效訪問
對于第二個問題,一般采取數(shù)字簽名的方法,要么通過數(shù)字證書簽名,要么通過像md5的方式,這就需要SSO系統(tǒng)返回免登URL的時候對需驗證的參數(shù)進行 md5加密,并帶上token一起返回,最后需免登的系統(tǒng)進行驗證信任關系的時候,需把這個token傳給SSO系統(tǒng),SSO系統(tǒng)通過對token的驗證 就可以辨別信息是否被改過
對于最后一個問題,可以通過白名單來處理,說簡單點只有在白名單上的系統(tǒng)才能請求生產信任關系,同理只有在白名單上的系統(tǒng)才能被免登錄。
相關文章
使用tp框架和SQL語句查詢數(shù)據(jù)表中的某字段包含某值
今天小編就為大家分享一篇使用tp框架和SQL語句查詢數(shù)據(jù)表中的某字段包含某值,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10Laravel 讀取 config 下的數(shù)據(jù)方法
今天小編就為大家分享一篇Laravel 讀取 config 下的數(shù)據(jù)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10