如何設計一個單點登陸系統(3)?

在上一篇文章git

如何設計一個單點登陸系統(2)?github

中主要講解了可跨域SSO系統服務端,客戶端在登陸,登出過程當中分別應該承擔的職責,本文將重點聊一下具體技術實現,源碼地址: https://github.com/zhoudapeng/zssoredis

首先聊服務端的實現,畢竟服務端是整個單點登陸系統的大腦spring

  1. 提供登陸頁,這個是登陸的基礎,全部的接入方在發現當前用戶未登陸的狀況下都會重定向到sso服務端的登陸頁,服務端的邏輯以下:跨域

如何設計一個單點登陸系統(3)?

sso服務端登陸頁邏輯緩存

這裏服務端須要作個判斷:cookie

  • 若是當前登陸存在.sso.com域下的有效cookie,則證實此用戶以前在其餘業務系統登陸過,此時無需再讓用戶登陸,只須要綁定token與此係統名的關係,而後重定向到此係統的回調接口(接入方須要在此回調接口中驗證token,建立本地會話)分佈式

  • 不存在.sso.com域下的有效cookie,證實此用戶未登陸過,須要跳轉到登陸頁,讓用戶登陸,爲了用戶登陸後能直接進入以前的頁面,這裏重定向的過程當中須要帶上redirectUrl 這個參數post

2.提供登陸接口,用戶在登陸頁輸入帳號密碼後會經過form表單已post的形式提交到此接口優化

如何設計一個單點登陸系統(3)?

sso服務端登陸form表單提交處理邏輯

  • 若是帳號密碼不對,則再次跳轉到登陸頁

  • 帳號密碼匹配,則須要建立token,綁定token與系統名的關係,寫全局cookie,而後重定向到接入方的回調地址

3.提供驗證token接口

如何設計一個單點登陸系統(3)?

sso服務端驗證token接口

  • token不存在,返回驗證失敗

  • token存在,則取出token的有效截止日期,並綁定token與系統名的關係

4.提供登出接口

如何設計一個單點登陸系統(3)?

sso服務端登出接口

登出時,須要根據token查到全部綁定過的系統名,而後調用各個系統的登出接口一一登出。

以上是服務端須要提供的4個接口,下面咱們再將一下客戶端的實現

在第一篇文章中講過,一個好的sso系統必需要讓接入方接入簡單,因此本人借鑑了spring auto-driven的思想,也提供了對應的命名空間,並抽象出了UrlHelper,UserStore,ZssoClient,ZssoConfigResolver4個組件,以及默認實現類,接入方在接入過程當中能夠隨意拓展這4個組件,而後直接注入到業務層上下文便可。

  • UrlHelper:拼接url的組件,如無特殊需求不建議從新實現

  • ZssoClient:跟服務端交互的組件,如無特殊需求不建議從新實現

  • ZssoConfigResolver:解析配置文件的組件,默認實現是讀取本地classpath下zsso-client.properties配置文件,如無特殊需求不建議從新實現

  • UserStore:存取用戶信息的組件,包括根據token解析用戶信息,綁定token與userId關係,解綁token,默認實現只是爲了演示用,接入方請務必本身實現此接口,並以userStore的名稱注入到業務層上下文中。

拓展組件使用方式:

如何設計一個單點登陸系統(3)?

拓展UserStore組件配置方式

在spring掃描掉<zsso:auto-driven/>時會去回調ZssoNamespaceHandler的init方法,最終執行ZssoBeanDefinitionParser的parse方法,在此方法中會去檢查每一個組件是否有注入對應的BeanDefinition,若是沒有則會自動注入默認實現類,核心代碼以下:

如何設計一個單點登陸系統(3)?

ZssoBeanDefinitionParser核心代碼

如何設計一個單點登陸系統(3)?

ComponentInitializer核心代碼

至此組件初始化的問題已經解決了,另外須要接入方開發的是以下問題:

  1. 判斷登陸狀態

  2. 登陸成功回調接口(包括check token的邏輯)

  3. 登出回調接口

既然每一個接入方都有這樣的共性,因此我提供了一個ZssoFilter,在Filter里根據不一樣的url作不一樣的處理,接入方只須要配置此Filter便可,Filter內部會自動去獲取組件,接入方只須要拓展相關組件便可,ZssoFilter核心代碼以下:

如何設計一個單點登陸系統(3)?

ZssoFilter核心邏輯

LoginCallbackFilter已封裝好解析請求參數中token,check token,建立本地會話,跳轉到原頁面等功能

LoginCheckFilter已封裝好判斷當前用戶是否登陸及跳轉到登陸頁的邏輯

LogoutFilter已封裝好刪除本地會話的功能

代碼中不少代碼都是演示類的,尤爲是server端的實現,好比保持用戶信息都是存的本地緩存,若是要放到生成環境則須要優化下這塊的邏輯,好比放到redis這樣的分佈式緩存等等。

最後很是感謝你們能在百忙中抽空看個人文章,你們的每一次查看都是我繼續寫文章的動力,因爲本人是典型理科男,文筆可能欠妥,但願你們可以繼續支持我,我也會繼續努力,繼續堅持原創,希望能讓你們都能有所收穫!

相關文章
相關標籤/搜索