1. 程式人生 > >Spring Security基於Oauth2的SSO單點登入怎樣做?一個註解搞定

Spring Security基於Oauth2的SSO單點登入怎樣做?一個註解搞定

![mark](https://img2018.cnblogs.com/blog/1769816/202003/1769816-20200302103628233-400360122.png) ## 一、說明 單點登入顧名思義就是在多個應用系統中,只需要登入一次,就可以訪問其他相互信任的應用系統,免除多次登入的煩惱。本文主要介紹 `同域` 和 `跨域` 兩種不同場景單點登入的實現原理,並使用 `Spring Security` 來實現一個最簡單的**跨域** `SSO客戶端` 。   ## 二、原理說明 單點登入主流都是基於共享 `cookie` 來實現的,下面分別介紹 `同域` 和 `跨域` 下的兩種場景具體怎樣實現共享 `cookie` 的 ### 2.1. 同域單點登入 **適用場景:**都是企業自己的系統,所有系統都使用同一個一級域名通過不同的二級域名來區分。 **舉個例子:**公司有一個一級域名為 `zlt.com` ,我們有三個系統分別是:**門戶系統(sso.zlt.com)**、**應用1(app1.zlt.com)**和**應用2(app2.zlt.com)**,需要實現系統之間的單點登入,實現架構如下: ![file](https://img2018.cnblogs.com/blog/1769816/202003/1769816-20200302103629459-1064642582.png) **核心原理:** 1. **門戶系統**設定 `Cookie` 的 `domain` 為一級域名也就是 `zlt.com`,這樣就可以共享門戶的 `Cookie` 給所有的使用該域名(`xxx.zlt.com`)的系統 2. 使用 `Spring Session` 等技術讓所有系統共享 `Session` 3. 這樣只要**門戶系統**登入之後無論跳轉**應用1**或者**應用2**,都能通過門戶 `Cookie` 中的 `sessionId` 讀取到 `Session` 中的登入資訊實現**單點登入**   ### 2.2. 跨域單點登入 單點登入之間的系統域名不一樣,例如第三方系統。由於域名不一樣不能共享 `Cookie` 了,這樣就需要通過一個單獨的授權服務(UAA)來做統一登入,並基於共享UAA的 `Cookie` 來實現單點登入。 **舉個例子:**有兩個系統分別是:**應用1(webApp.com)**和**應用2(zlt.com)**需要實現單點登入,另外有一個**UAA授權中心(sso.com)**,實現架構如下: ![file](https://img2018.cnblogs.com/blog/1769816/202003/1769816-20200302103630466-278116735.png) **核心原理:** 1. 訪問**系統1**判斷未登入,則跳轉到**UAA系統**請求授權 2. 在**UAA系統**域名 `sso.com` 下的登入地址中輸入使用者名稱/密碼完成登入 3. 登入成功後**UAA系統**把登入資訊儲存到 `Session` 中,並在瀏覽器寫入域為 `sso.com` 的 `Cookie` 4. 訪問**系統2**判斷未登入,則跳轉到**UAA系統**請求授權 5. 由於是跳轉到**UAA系統**的域名 `sso.com` 下,所以能通過瀏覽器中UAA的 `Cookie` 讀取到 `Session` 中之前的登入資訊完成**單點登入**   ### 2.3. 基於Oauth2的跨域單點登入流程 ![mark](https://img2018.cnblogs.com/blog/1769816/202003/1769816-20200302103630919-1975865190.png) >關於Oauth2的授權碼模式這裡就不做介紹了,自行找資料瞭解   ## 三、Spring Security實現 **Oauth2單點登入**除了需要**授權中心**完成統一登入/授權邏輯之外 >基於 `Spring Security` 實現的**UUA統一授權中心**可以參考:[https://gitee.com/zlt2000/microservices-platform/tree/master/zlt-uaa](https://gitee.com/zlt2000/microservices-platform/tree/master/zlt-uaa) 各個系統本身(sso客戶端)也需要實現以下邏輯: 1. 攔截請求判斷登入狀態 2. 與 `UAA授權中心` 通過 `Oauth2授權碼模式` 互動完成登入/單點登入 3. 儲存使用者登入資訊 以上邏輯只需使用一個 `@EnableOAuth2Sso` 註解即可實現 ![mark](https://img2018.cnblogs.com/blog/1769816/202003/1769816-20200302103631079-371120314.png) SpringBoot配置如下: ![mark](https://img2018.cnblogs.com/blog/1769816/202003/1769816-20200302103631466-1907017845.png) 下圖是訪問 `sso客戶端` 時 `@EnableOAuth2Sso` 註解與 `UAA授權中心` 通過 `Oauth2授權碼模式` 互動完成單點登入的步驟 ![mark](https://img2018.cnblogs.com/blog/1769816/202003/1769816-20200302103632365-1267384203.png) >請結合上面單點時序圖中**單點登入系統2**的1~5步 **PS**:如果系統用的不是 `Spring Security` 怎麼辦?理解原理自行實現   ## 四、demo下載地址 [https://gitee.com/zlt2000/microservices-platform/tree/master/zlt-demo/sso-demo](https://gitee.com/zlt2000/microservices-platform/tree/master/zlt-demo/sso-demo)   **掃碼關注有驚喜!** ![file](https://img2018.cnblogs.com/blog/1769816/202003/1769816-20200302103632878-1405789