天天看點

基于Spring的簡易SSO設計

1、元件圖

基于Spring的簡易SSO設計

主要由3大部分組成,

1.1 SSO Client Filter 類似Asp.Net中的HttpMudule,用來攔截client webapp的所有請求,如果發現Cookie中沒有已登入的token辨別,則将請求重定向到sso 站點的login頁面;此外,它還用于接收SSO登入成功後傳回的token辨別

1.2 SSO App 即SSO的主站點,提供統一的登入認證,并将認證後的token傳回給Client WebApp;以及驗證Client WebApp發送來的token是否合法。

1.3 Token Store ,用于存放所有目前登入成功的token-user的映射關系,通常是一個key-value的hash結構,通過token(key),可找到相應的使用者(value)關鍵資訊(比如:使用者名等),實體上,可用cache server/nosql db等輕量級的産品實作。

2、部署圖

基于Spring的簡易SSO設計

3、SSO Client Filter的序列圖

verify token(A)

基于Spring的簡易SSO設計

解釋:

當使用者要通路Client Website中的某個頁面時,該請求首先被SSO Client Filter攔截,然後按以下流程處理:

1. 先從cookie中查找token辨別

2. 如果沒找到token

3. 直接重定向到sso的login頁面,并在returnURL參數中,将請求頁面傳遞給sso

3.1 登入成功後,生成一個token字元串,然後将token-user info的映射關系,存入token server

3.2 同時重定向到Client Website登入前的頁面,并在url中附加一個token參數

3.2.1 Client Website收到傳回的token url參數後,寫入Cookie

3.2.2 将token參數從url中去掉,重定向到登入前的請求頁面(即:returnURL)

轉入下面的處理: 

verify token(B)

基于Spring的簡易SSO設計

1.再次從cookie中查找token

2.如果找到,則請求sso site驗證token的合法性(因為cookie中的token有可能是僞造的,或者已經失效),并帶上returnURL(以便驗證通過後,能重定向到使用者需要通路的頁面)

3 sso收到請求的token後,到token server中驗證真僞(帶上目前請求頁面位址,做為returnUrl附帶在url參數中)

4 token server傳回驗證結果

5 如果校驗失敗,則跳轉到登入頁面,要求重新登入(帶returnUrl)

6 如果驗證通過,傳回成功辨別

7 子站點拿到成功辨別後,大功告成,剩下該幹啥幹嘛(即:正常執行頁面上的正常處理)

驗證通過後,再通路其它頁面時,因為本地cookie中已經有token辨別,是以将直接執行 verify token(B)處理。

性能分析:

從前面的分析可以看出,即使第一次認證成功後,後續的每個頁面請求都要到SSO上驗證token的真僞,這樣如果并發使用者比較多,SSO的壓力略大,可以在client website中增加二級緩存,首次驗證通過後,将token-user info的映射關系,存入Client Website自己的緩存中,這樣後續其它頁面驗證token時,直接到client website的cache中驗證即可,但這樣做的前提是client website中的token cache過期時間一定要小于sso token server中的過期時間,否則SSO Token Server中的token已經失效,但是client website中的token仍有效,就失去驗證token真僞的意義了。另外,這樣處理後,性能雖然提高了,但安全性從理論上講,将所有折扣。

安全性分析:

token的生成算法很關鍵,不要與使用者名、密碼、使用者角色等這些敏感資訊相關,要保證生成的唯一字元串沒有實際業務意義(比如:可用uuid/guid之類),同時若cookie中token被竊取,為了将危害降到最低,每次token驗證成功後,最好重新生成新的token,類似手機動态密碼一樣,用過即換。

與Spring的關系:

講了半天,似乎沒看到任何Spring的影子,以上其實是SSO的通用思路,技術上适用于任何主流web技術,Spring-Security可以很容易實作SSO的使用者Form Login登入認證,而Token Server可以用Spring-Cache來實作,至于SSO Client Filter、Client Website,Spring-MVC/Servlet Filter可以輕松搞定。

如何擴充到c/s應用

雖然SSO在很多情況下,用于整合web子系統,但隻要略加改造,c/s應用其實也可以套用這個思路,比如:可以指定硬碟上某個xml檔案(或windows系統資料庫中自己建立一個項)用來儲存token(相當于浏覽器的cookie存儲token),c/s的每個視窗統一繼承至某個父視窗,在父視窗中,每次打開時,檢測該xml中是否有token(相當于sso client filter所做的事情),如果沒有,則彈出登入視窗,将使用者名、密碼參數,發送到sso進行認證(相當于重定向到sso的login頁面認證),認證成功後,将服務端傳回的token寫入本地xml(相當于sso client filter接收token)