自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

實(shí)現(xiàn)SSO單點(diǎn)登錄的思考

開(kāi)發(fā) 前端
隨著公司業(yè)務(wù)的發(fā)展,子系統(tǒng)越來(lái)越多,實(shí)現(xiàn)SSO單點(diǎn)登錄的需求就愈加迫切。

[[360300]]

隨著公司業(yè)務(wù)的發(fā)展,子系統(tǒng)越來(lái)越多,實(shí)現(xiàn)SSO單點(diǎn)登錄的需求就愈加迫切。

我們一些子系統(tǒng)中都有使用Redis存儲(chǔ)Session,這最初是為了解決應(yīng)用集群部署時(shí)的Session共享問(wèn)題,卻也為應(yīng)用之間共享Session提供了支持,但單靠應(yīng)用之間共享Session是無(wú)法實(shí)現(xiàn)單點(diǎn)登錄的。

在單應(yīng)用中,當(dāng)用戶登錄系統(tǒng)后,用戶的登錄狀態(tài)被存儲(chǔ)在服務(wù)端的Session中,并通過(guò)響應(yīng)頭的Cookie字段將SessionId傳遞給瀏覽器存儲(chǔ),后續(xù)請(qǐng)求服務(wù)端時(shí),瀏覽器會(huì)自動(dòng)在請(qǐng)求頭加上Cookie,所以才能保持用戶的登錄狀態(tài)。

使用Redis共享Session,集群之間可以共享Session的原理與服務(wù)重啟后依然保持登錄狀態(tài)的原理相同。

在應(yīng)用重啟后,由于瀏覽器還是攜帶cookie發(fā)起請(qǐng)求,如果Session未過(guò)期,那么從Redis獲取到的Session就能繼續(xù)使用。

由此可見(jiàn),雖然應(yīng)用之間可通過(guò)Redis共享Session,但要求瀏覽器向每個(gè)應(yīng)用發(fā)起請(qǐng)求都能帶上相同Cookie才能實(shí)現(xiàn)單點(diǎn)登錄。

然瀏覽器卻不支持不同域名之間Cookie共享,服務(wù)端也不能操控客戶端瀏覽器訪問(wèn)不同域名下的站點(diǎn)都帶上相同的SessionId。要實(shí)現(xiàn)單點(diǎn)登錄我們只能另辟蹊徑。

雖然瀏覽器不支持不同域名之間共享Cookie,但同一個(gè)主域名的不同子域名應(yīng)用間可通過(guò)配置Cookie為主域名方式實(shí)現(xiàn)Cookie共享,前提是所有子系統(tǒng)都共用一個(gè)主域名。這種方案可取也不可取,短期而言可取,長(zhǎng)期而言不可取。

如果只是實(shí)現(xiàn)web應(yīng)用之間相互跳轉(zhuǎn),由用戶在應(yīng)用a點(diǎn)擊按鈕跳轉(zhuǎn)到應(yīng)用b,也可以這樣實(shí)現(xiàn):當(dāng)用戶在應(yīng)用a點(diǎn)擊跳轉(zhuǎn)應(yīng)用b時(shí),在跳轉(zhuǎn)鏈接上帶上SessionId,應(yīng)用b根據(jù)SessionId讀取用戶信息再寫入Session。

先不討論安全性如何,這種方式的弊端也很明顯,用戶不能直接在瀏覽器輸入應(yīng)用B的域名跳轉(zhuǎn),而只能通過(guò)應(yīng)用A跳轉(zhuǎn)到應(yīng)用B,要返回應(yīng)用A也只能從應(yīng)用B點(diǎn)擊按鈕跳轉(zhuǎn)回應(yīng)用A。

雖然通過(guò)點(diǎn)擊按鈕方式實(shí)現(xiàn)應(yīng)用之間互相跳轉(zhuǎn)不是一個(gè)好的計(jì)策,但至少通過(guò)在跳轉(zhuǎn)鏈接上攜帶SessionId共享登錄狀態(tài)這個(gè)思路是可取的。

根據(jù)這個(gè)思路,我們是否可以實(shí)現(xiàn)不通過(guò)點(diǎn)擊按鈕方式也能讓瀏覽器自動(dòng)帶上SessionId呢?

可以,但要通過(guò)重定向?qū)崿F(xiàn)。

當(dāng)用戶在系統(tǒng)A登錄后,直接在瀏覽器上修改域名訪問(wèn)系統(tǒng)B時(shí),系統(tǒng)B檢查到用戶未登錄后將請(qǐng)求重定向到系統(tǒng)A,系統(tǒng)A檢查到請(qǐng)求從系統(tǒng)B重定向過(guò)來(lái),并且用戶已經(jīng)登錄,那么可將SessionId拼接到重定向鏈接上,再重定向回系統(tǒng)B。系統(tǒng)B獲取到系統(tǒng)A的SessionId,然后根據(jù)SessionId從Redis查詢用戶信息,再寫入系統(tǒng)B的Session中。如此就能實(shí)現(xiàn)自動(dòng)攜帶SessionId跳轉(zhuǎn)。

只不過(guò),這種方式要求每個(gè)系統(tǒng)都實(shí)現(xiàn)一遍這樣的功能,并且每個(gè)系統(tǒng)也都要提供登錄功能。

為了簡(jiǎn)化實(shí)現(xiàn),以及后續(xù)的新系統(tǒng)不再重復(fù)實(shí)現(xiàn)登錄功能,我們應(yīng)該考慮將登錄功能抽離為一個(gè)獨(dú)立的應(yīng)用,其它系統(tǒng)不再提供登錄功能。

將登錄功能抽離為獨(dú)立應(yīng)用之后,實(shí)現(xiàn)SSO單點(diǎn)登錄流程梳理如下:

將SSO抽離為一個(gè)獨(dú)立的應(yīng)用,獨(dú)立的域名,提供登錄頁(yè)面,要求其它應(yīng)用不再提供登錄頁(yè)面,都必須通過(guò)SSO登錄。

其它應(yīng)用在接收到請(qǐng)求時(shí),首先根據(jù)session判斷是否已經(jīng)登錄了,如果未登錄則重定向到SSO登錄頁(yè)面,并且在重定向鏈接帶上是哪個(gè)應(yīng)用跳轉(zhuǎn)過(guò)來(lái)的,當(dāng)用戶在SSO登錄成功后重定向回原來(lái)的應(yīng)用。

瀏覽器重定向到SSO登錄頁(yè)面時(shí),瀏覽器會(huì)存儲(chǔ)SSO的cookie,用戶在SSO登錄成功后,SSO存儲(chǔ)用戶的登錄狀態(tài)。SSO生成一個(gè)token,重定向回原應(yīng)用,在重定向鏈接上帶上token。

原應(yīng)用檢查請(qǐng)求攜帶token,這時(shí)需要訪問(wèn)SSO驗(yàn)證token并獲取用戶信息,SSO驗(yàn)證成功后返回用戶信息,原應(yīng)用將用戶信息存儲(chǔ)到Session中,驗(yàn)證成功后再重定向到首頁(yè)。

如果用戶此時(shí)通過(guò)在瀏覽器輸入應(yīng)用B的域名訪問(wèn)應(yīng)用B,由于應(yīng)用B檢查到Session沒(méi)有用戶信息(未登錄),于是重定向到SSO應(yīng)用。

因?yàn)橛脩粼赟SO登錄過(guò)了,重定向請(qǐng)求SSO應(yīng)用時(shí)瀏覽器會(huì)帶上cookie,所以SSO應(yīng)用發(fā)現(xiàn)用戶已經(jīng)登錄,于是生成一個(gè)token并重定向回應(yīng)用B。

應(yīng)用B接收重定向請(qǐng)求,從請(qǐng)求中獲取到token,接著訪問(wèn)sso應(yīng)用驗(yàn)證token并獲取用戶信息,在獲取用戶信息成功后再寫入Session,最后重定向到首頁(yè)。

根據(jù)梳理的流程,總結(jié)每個(gè)應(yīng)用需要實(shí)現(xiàn)的功能:

SSO應(yīng)用:

提供登錄功能,支持從哪個(gè)應(yīng)用重定向過(guò)來(lái),登錄成功后就重定向回哪個(gè)應(yīng)用去;

提供根據(jù)token獲取當(dāng)前登錄用戶信息的接口。

其它應(yīng)用:

未登錄則重定向跳轉(zhuǎn)到SSO,在跳轉(zhuǎn)鏈接上帶上登錄成功后重定向調(diào)用的接口;

提供給SSO重定向調(diào)用的接口,用于接收SSO傳遞的token,根據(jù)token從SSO獲取登錄用戶信息,將用戶信息寫入Session,最后重定向到前端首頁(yè)。

在前后端分離的系統(tǒng)上實(shí)現(xiàn)這一流程并不容易,實(shí)際實(shí)現(xiàn)比本文描述的步驟還要多。

我們通過(guò)封裝SDK的方式,盡可能將繁瑣的步驟封裝起來(lái),讓其它應(yīng)用對(duì)接SSO時(shí)僅需要依賴一個(gè)jar包,并添加少量的配置。

SDK通過(guò)Servlet提供的過(guò)濾器攔截所有請(qǐng)求:

1、如果請(qǐng)求是“/checketSsoToken”,則說(shuō)明是用戶在SSO登錄成功后(瀏覽器重定向)跳轉(zhuǎn)過(guò)來(lái)的,并且會(huì)攜帶token參數(shù)。此時(shí)SDK需要請(qǐng)求SSO檢驗(yàn)token,并將獲取的用戶信息寫入Session中,然后重定向到當(dāng)前應(yīng)用的前端首頁(yè)。

2、如果不是“/checketSsoToken”,則查看配置,判斷當(dāng)前請(qǐng)求是否不需要登錄也可放行,如果是則放行,否則判斷Session中是否記錄用戶已經(jīng)登錄,如果未登錄,則響應(yīng)重定向,由前端跳轉(zhuǎn)到SSO登錄。

由于前后端分離,前端通過(guò)ajax請(qǐng)求接口,后端判斷未登錄響應(yīng)重定向無(wú)法真正重定向,所以要求前端攔截所有請(qǐng)求的響應(yīng),如果響應(yīng)頭有重定向標(biāo)志,應(yīng)從請(qǐng)求頭獲取重定向鏈接,然后讓瀏覽器重定向。

3、如果是退出登錄請(qǐng)求,則先清除應(yīng)用自身緩存的用戶登錄信息,再重定向到SSO退出登錄。

實(shí)際實(shí)現(xiàn)的單點(diǎn)登錄流程如下:

1、用戶在瀏覽器中輸入應(yīng)用A的域名,要跳轉(zhuǎn)到前端的index.html頁(yè)面;(nginx反向代理配置實(shí)現(xiàn))

2、前端在首頁(yè)調(diào)用一個(gè)后端接口,如獲取菜單,觸發(fā)校驗(yàn)登錄(前端實(shí)現(xiàn)),未登錄則拼接重定向鏈接,響應(yīng)給前端,要求重定向到SSO登錄頁(yè)面(SDK封裝實(shí)現(xiàn));

3、用戶在SSO登錄成功后,由SSO重定向調(diào)用應(yīng)用A的“/checketSsoToken”。此url在應(yīng)用A重定向到SSO登錄時(shí)作為參數(shù)拼接在URL后面,由后端提供,前端只負(fù)責(zé)重定向;(SSO應(yīng)用實(shí)現(xiàn))

4、應(yīng)用A請(qǐng)求SSO的校驗(yàn)token接口,并將響應(yīng)的用戶信息寫入session,重定向回前端首頁(yè)。(SDK封裝實(shí)現(xiàn))

需要注意的是,假設(shè)SSO設(shè)置的session過(guò)期時(shí)間為一個(gè)小時(shí),如果用戶在SSO登錄后跳轉(zhuǎn)回應(yīng)用A,一個(gè)小時(shí)不操作后再跳轉(zhuǎn)應(yīng)用B,此時(shí)會(huì)因?yàn)镾SO的session已經(jīng)過(guò)期導(dǎo)致無(wú)法同步登錄狀態(tài),用戶就得要重新登錄,所以SSO的session過(guò)期時(shí)間應(yīng)該根據(jù)需要合理設(shè)置,不應(yīng)該設(shè)置太短。

最后留下一道思考題:如何同步退出登錄狀態(tài)?

當(dāng)用戶在應(yīng)用A退出登錄時(shí),只有應(yīng)用A和SSO知道用戶退出登錄了,但其它應(yīng)用卻不得而知。

最簡(jiǎn)單的方式就是除SSO之后,將其它應(yīng)用的Session過(guò)期時(shí)間配置盡可能短。又或者每次打開(kāi)應(yīng)用的首頁(yè)都先跳轉(zhuǎn)到SSO,如果已經(jīng)登錄,自然會(huì)重定向回來(lái),這一個(gè)步驟對(duì)用戶來(lái)說(shuō)是透明的。

 

最后,由于每個(gè)應(yīng)用都用了Shiro實(shí)現(xiàn)接口權(quán)限校驗(yàn),也用了Shiro的注解,所以權(quán)限校驗(yàn)的實(shí)現(xiàn),我們?cè)赟DK適配了Shiro的注解,但完全棄用了Shiro。

本文轉(zhuǎn)載自微信公眾號(hào)「Java藝術(shù)」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系Java藝術(shù)公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: Java藝術(shù)
相關(guān)推薦

2024-06-21 09:28:43

2021-10-29 13:26:54

單點(diǎn)登錄SSO

2024-03-01 11:33:31

2024-08-12 08:12:38

2024-09-27 12:13:26

GoGTokenSSO

2022-05-12 07:37:51

單點(diǎn)登錄微服務(wù)開(kāi)源

2021-01-18 06:21:18

登錄SSO接口

2023-11-08 14:57:41

2022-11-28 09:19:33

2021-09-28 10:48:07

開(kāi)源雙因素認(rèn)證單點(diǎn)登錄

2024-09-11 08:37:39

2021-06-01 06:01:35

SSO單點(diǎn)登錄

2016-12-26 18:05:00

單點(diǎn)登錄原理簡(jiǎn)單實(shí)現(xiàn)

2021-06-24 08:52:19

單點(diǎn)登錄代碼前端

2023-12-11 13:05:21

2024-12-06 07:00:00

2014-02-25 10:37:16

自動(dòng)化運(yùn)維SSO單點(diǎn)登錄

2012-02-14 14:17:35

ibmdw

2023-08-29 08:00:38

2013-10-16 15:17:30

vCenter單點(diǎn)登錄
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)