最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring boot如何基于JWT實現(xiàn)單點登錄詳解

 更新時間:2019年06月14日 10:23:05   作者:fleyX  
這篇文章主要介紹了spring boot如何基于JWT實現(xiàn)單點登錄詳解,用戶只需登錄一次就能夠在這兩個系統(tǒng)中進(jìn)行操作。很明顯這就是單點登錄(Single Sign-On)達(dá)到的效果,需要的朋友可以參考下

前言

最近我們組要給負(fù)責(zé)的一個管理系統(tǒng) A 集成另外一個系統(tǒng) B,為了讓用戶使用更加便捷,避免多個系統(tǒng)重復(fù)登錄,希望能夠達(dá)到這樣的效果——用戶只需登錄一次就能夠在這兩個系統(tǒng)中進(jìn)行操作。很明顯這就是單點登錄(Single Sign-On)達(dá)到的效果,正好可以明目張膽的學(xué)一波單點登錄知識。

本篇主要內(nèi)容如下:

  • SSO 介紹
  • SSO 的幾種實現(xiàn)方式對比
  • 基于 JWT 的 spring boot 單點登錄實戰(zhàn)

注意:

SSO 這個概念已經(jīng)出現(xiàn)很久很久了,目前各種平臺都有非常成熟的實現(xiàn),比如OpenSSO,OpenAM,Kerberos,CAS等,當(dāng)然很多時候成熟意味著復(fù)雜。本文不討論那些成熟方案的使用,也不考慮 SSO 在 CS 應(yīng)用中的使用。

什么是 SSO

單點點說就是:一次登錄后可免登陸訪問其他的可信平臺。比如我們登錄淘寶網(wǎng)后,再打開天貓首頁可以發(fā)現(xiàn)已經(jīng)是登錄狀態(tài)了。SSO 是一種比較流行的服務(wù)于企業(yè)業(yè)務(wù)整合的一種解決方案。

如何實現(xiàn) SSO

我們都知道目前的 http 協(xié)議是無狀態(tài)的,也就是第一次請求和第二次請求是完全獨立,不相關(guān)的,但現(xiàn)實中我們的業(yè)務(wù)邏輯都是有狀態(tài)的,這樣就引入了 cookie-session 的機制來維護狀態(tài),瀏覽器端存儲一個 sessionId,后臺存儲跟該 sessionId 相關(guān)的數(shù)據(jù)。每次向后臺發(fā)起請求時都攜帶此 sessionId 就能維持狀態(tài)了。然后就有了 cookie,瀏覽器在發(fā)送請求時自動將 cookie 中的數(shù)據(jù)放到請求中,發(fā)給服務(wù)端,無需手動設(shè)置。

然后我們可以考慮考慮實現(xiàn) SSO 的核心是什么?答案就是如何讓一個平臺 A 登錄后,其他的平臺也能獲取到平臺 A 的登錄信息(在 cookie-session 機制中就是 sessionId)。

方案一 共享 cookie

基于 cookie-session 機制的系統(tǒng)中,登錄系統(tǒng)后會返回一個 sessionId 存儲在 cookie 中,如果我們能夠讓另外一個系統(tǒng)也能獲取到這個 cookie,不就獲取到憑證信息了,無需再次登錄。剛好瀏覽器的 cookie 可以實現(xiàn)這樣的效果(詳見web 跨域及 cookie 學(xué)習(xí))。

cookie 允許同域名(或者父子域名)的不同端口中共享 cookie,這點和 http 的同域策略不一樣(http 請求只要協(xié)議、域名、端口不完全相同便認(rèn)為跨域)。因此只需將多個應(yīng)用前臺頁面部署到相同的域名(或者父子域名),然后共享 session 便能夠?qū)崿F(xiàn)單點登錄。架構(gòu)如下:

上面方案顯而易見的限制就是不僅前臺頁面需要共享 cookie,后臺也需要共享 session(可以用jwt來干掉 session,但是又會引入新的問題,這里不展開).這個方案太簡單了,不作進(jìn)一步說明。

方案二 基于回調(diào)實現(xiàn)

通過上文可以知道,要實現(xiàn)單點登錄只需將用戶的身份憑證共享給各個系統(tǒng),讓后臺知道現(xiàn)在是誰在訪問。就能實現(xiàn)一次登錄,到處訪問的效果,實在是非常方便的。在 session 機制中是共享 sessionId,然后多個后臺使用同一個 session 源即可。這里我們用一種新的基于 JWT 的 token 方式來實現(xiàn),不了解 JWT 的可以看這篇:java-jwt 生成與校驗,簡單來說 jwt 可以攜帶無法篡改的信息(一段篡改就會校驗失敗),所以我們可以將用戶 id 等非敏感信息直接放到 jwt 中,干掉了后臺的 session。然后我們要做的就是將 jwt 共享給各個平臺頁面即可。系統(tǒng)架構(gòu)如下:

此架構(gòu)中,業(yè)務(wù)系統(tǒng) A 和業(yè)務(wù)系統(tǒng) B 之間不需要有任何聯(lián)系,他們都只和 SSO 認(rèn)證平臺打交道,因此可以任意部署,沒有同域的限制。你可能就要問了這樣要怎么共享身份憑證(也就是 jwt 字符串)?這里就要通過 url 參數(shù)來進(jìn)行騷操作了。

文字總結(jié)來說是這樣的:jwt 存到認(rèn)證平臺前端的 localStore(不一定是 localStore,cookie,sessionStore 都可以),然后業(yè)務(wù)平臺攜帶自己的回調(diào)地址跳轉(zhuǎn)到認(rèn)證中心的前臺,認(rèn)證中心的前臺再將 ujwt 作為 url 參數(shù),跳回到那個回調(diào)地址上,這樣就完成了 jwt 的共享。

文字很可能看不懂,下面是整個過程的路程圖:

相信通過上面的流程圖你應(yīng)該能大概看明白,jwt 是如何共享了的吧,還看不懂的繼續(xù)看下來,下面上一個 spring boot 實現(xiàn)的簡易 SSO 認(rèn)證。主要有兩個系統(tǒng):SSO 認(rèn)證中心,系統(tǒng) A(系統(tǒng) A 換不同端口運行就是系統(tǒng) A、B、C、D 了).

實戰(zhàn)

實現(xiàn) SSO 認(rèn)證中心

spring boot 框架先搭起來,由于是簡易項目,除 spring boot web 基本依賴,只需要如下的額外依賴:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.7.0</version>
</dependency>

完整的 POM 文件,請到 github 上查看.

后臺實現(xiàn)

后臺做的事情并不多,只有以下 5 個方法:

  • /login : 登錄成功后簽發(fā)一個 jwt token

在 demo 中只是簡單對比用戶名密碼如果是一樣的認(rèn)為登錄成功,返回 token

  • /checkJwt : 檢查 jwt 的有效性

檢查傳來的 jwt-token 是否有效,返回失效的 jwt 列表

  • /refreshjwt : 刷新 jwt

判斷該 jwt 是否快要過期,如果快要過期,生成一個新的 jwt 返回

  • /inValid : 讓某個 jwt 失效

jwt 如何失效一直是一個比較麻煩的問題,各有利弊。本例中采用的是為每個 jwt 生成一個隨機的秘鑰 secret,將 jwt–secret 保存到 redis 中,想要讓某個 jwt 失效,只需將該記錄在 redis 中刪除即可(這樣在解密時便無法獲取到 secret)。但是這樣讓無狀態(tài)的認(rèn)證機制變成有狀態(tài)了(記錄了 jwt 和 secret 的對應(yīng)關(guān)系)。

總結(jié)來說 SSO 后臺主要只做了兩件事:驗證用戶名密碼返回 jwt;驗證 jwt 是否合法。具體代碼查看 github 上 sso 目錄下的代碼。

前臺實現(xiàn)

前臺的邏輯較為復(fù)雜,不是那么容易理解,不明白的多看幾遍上面的流程圖。

再次回到 SSO 的重點:分享登錄狀態(tài)。要如何在前臺將登錄狀態(tài)(在這里就是 jwt 字符串)分享出去呢?由于瀏覽器的限制,除了 cookie 外沒有直接共享數(shù)據(jù)的辦法。既然沒有直接共享,那肯定是有間接的辦法的!

這個辦法就是回調(diào)。系統(tǒng) A 的前臺在跳轉(zhuǎn)到 SSO 的前臺時,將當(dāng)前路徑作為 url 參數(shù)傳遞給 sso 前臺,sso 前臺在獲取到 jwt 后,再跳轉(zhuǎn)到系統(tǒng) A 傳過來的 url 路徑上,并帶上 jwt 作為 url 參數(shù)。這就完成了 jwt 的一次共享,從 sso 共享到系統(tǒng) A。

打個比方:你點了個外賣,別人要怎么把外賣給你呢?顯然你會留下的地址,讓別人帶上飯送到這個地址,然后你就能享用美食了。這和 jwt 的傳遞非常相識了。

系統(tǒng) A 說:我要 jwt,快把它送到http://localhost:8081/test1/這個地址上。

SSO 說:好嘞,這個地址是合法的可以送 jwt 過去,這就跳轉(zhuǎn)過去:http://localhost:8081/test1/?jwt=abcdefj.asdf.asdfasf

系統(tǒng) A 說:不錯不錯,真香。

要注意這里有個坑就是:如果另外一個惡意系統(tǒng) C 安裝相同的格式跳轉(zhuǎn)到 SSO,想要獲取 jwt,這顯然是不應(yīng)該給它的。所以在回跳回去的時候要判斷一下這個回調(diào)地址是不是合法的,能不能給 jwt 給它,可以向后臺請求判斷也可以在 sso 前臺直接寫死合法的地址。在 demo 是沒有這個判斷過程的。

實現(xiàn)業(yè)務(wù)系統(tǒng)

業(yè)務(wù)系統(tǒng)代碼非常簡單,主要是用了一個攔截器,攔截 http 請求,提取出 token 向 sso 認(rèn)證中心驗證 token 是否有效,有效放行,否則返回錯誤給前端。太簡單也不貼代碼了,到 github 上看看就明白了。

效果

上面說了一大串都是原理了,其實這個難也就難在原理部分,代碼實現(xiàn)并沒有那么復(fù)雜。這里就不貼代碼了,有需要直接到 github 上看。

這里上幾個效果圖:

系統(tǒng) A 首次登陸系統(tǒng)


可以看到首次登陸是需要跳到 sso 認(rèn)證中心輸入用戶名密碼進(jìn)行登陸驗證的。登陸成功回跳后接口請求成功。

將 A 的啟動端口改為 8082 后再次啟動,當(dāng)作系統(tǒng) B

可以看到這次是無需登陸的,跳到認(rèn)證中心后就馬上跳回了,如果去掉 alert 一般是看不出跳轉(zhuǎn)過程的。

最后在任意一個系統(tǒng)注銷,都會讓所有的系統(tǒng)推出登陸。

可以看到,在系統(tǒng) A 登錄系統(tǒng)后,系統(tǒng) B,系統(tǒng) C 都不再需要輸入用戶名密碼進(jìn)行登錄。如果速度足夠快甚至都注意不到調(diào)到 SSO 再跳回來的過程。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring Cloud Gateway 獲取請求體(Request Body)的多種方法

    Spring Cloud Gateway 獲取請求體(Request Body)的多種方法

    這篇文章主要介紹了Spring Cloud Gateway 獲取請求體(Request Body)的多種方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • SpringMVC核心DispatcherServlet處理流程分步詳解

    SpringMVC核心DispatcherServlet處理流程分步詳解

    這篇文章主要介紹了SpringMVC核心之中央調(diào)度器DispatcherServlet的相關(guān)知識,包括SpringMVC請求處理過程及SrpingMVC容器和spring IOC容器關(guān)系,需要的朋友可以參考下
    2023-04-04
  • java模擬ajax訪問另一個項目的controller代碼實例

    java模擬ajax訪問另一個項目的controller代碼實例

    今天小編就為大家分享一篇關(guān)于java模擬ajax訪問另一個項目的controller代碼實例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 使用java模擬簡單的tomcat的方法詳解

    使用java模擬簡單的tomcat的方法詳解

    這篇文章主要為大家詳細(xì)介紹了java模擬簡單的tomcat的方法,使用數(shù)據(jù)庫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java SSM配置文件案例詳解

    Java SSM配置文件案例詳解

    這篇文章主要介紹了Java SSM配置文件案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 詳解Java 線程中斷

    詳解Java 線程中斷

    這篇文章主要介紹了Java 線程中斷的相關(guān)資料,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-02-02
  • MyBatis 參數(shù)綁定的具體實現(xiàn)

    MyBatis 參數(shù)綁定的具體實現(xiàn)

    本文主要介紹了MyBatis 參數(shù)綁定的具體實現(xiàn),包括默認(rèn)參數(shù)名、@Param注解和POJO/DTO對象三種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-01-01
  • Java接口回調(diào)和方法回調(diào)的簡單實現(xiàn)步驟

    Java接口回調(diào)和方法回調(diào)的簡單實現(xiàn)步驟

    這篇文章主要介紹了Java接口回調(diào)和方法回調(diào)的相關(guān)資料,接口回調(diào)是一種設(shè)計模式,實現(xiàn)三方解耦,調(diào)用者提供接口實現(xiàn),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-03-03
  • Java的關(guān)鍵字與標(biāo)識符小結(jié)

    Java的關(guān)鍵字與標(biāo)識符小結(jié)

    這篇文章主要介紹了Java的關(guān)鍵字與標(biāo)識符,總結(jié)整理了Java各種常見的關(guān)鍵字與標(biāo)識符功能、用法及操作注意事項,需要的朋友可以參考下
    2020-04-04
  • 詳解springboot 使用c3p0數(shù)據(jù)庫連接池的方法

    詳解springboot 使用c3p0數(shù)據(jù)庫連接池的方法

    本篇文章主要介紹了springboot 使用c3p0數(shù)據(jù)庫連接池的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09

最新評論

和顺县| 新巴尔虎左旗| 蓬莱市| 积石山| 湄潭县| 正阳县| 和静县| 贵定县| 六枝特区| 栾城县| 肇东市| 安阳县| 凤翔县| 林州市| 左云县| 平武县| 九龙坡区| 高青县| 正蓝旗| 长宁区| 东兰县| 浪卡子县| 抚远县| 卢龙县| 乐亭县| 罗山县| 九龙城区| 东方市| 玉山县| 沧州市| 喀喇沁旗| 四平市| 福贡县| 本溪| 昌宁县| 遵义县| 河北省| 马关县| 方城县| 新乡县| 从化市|