<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用 OIDC 在一個(gè) Keycloak 中集成另一個(gè) Keycloak 用戶認(rèn)證

          共 7175字,需瀏覽 15分鐘

           ·

          2021-04-02 15:37

          這是一篇價(jià)值 7 元的文章,有人已經(jīng)付費(fèi),免費(fèi)分享給你!


          周末有人在知乎上通過付費(fèi)咨詢頻道問我,如何在一個(gè) Keycloak 中集成另一個(gè) Keycloak 用戶認(rèn)證。由于目前知乎付費(fèi)咨詢只支持手機(jī)端,因此我當(dāng)時(shí)的回答比較簡略的。今天再用電腦把實(shí)現(xiàn)步驟一步一步寫下來,爭取讓小白也能夠順利集成,因此文章會(huì)略顯啰嗦,高手請(qǐng)選擇性地跳躍閱讀或者直接忽略。



          問題重述


          我看了你關(guān)于《基于 keycloak 的關(guān)注公眾號(hào)即登錄功能的設(shè)計(jì)與實(shí)現(xiàn)》的文章,有點(diǎn)問題想和你溝通下。

          我現(xiàn)在有2個(gè)系統(tǒng),a和b。它們都接入了keycloak,是2個(gè)realm。數(shù)據(jù)庫也是隔離的?,F(xiàn)在想要實(shí)現(xiàn)a系統(tǒng)通過b系統(tǒng)的賬號(hào)登錄。我想用類似微信登錄的方式,把b系統(tǒng)當(dāng)成微信。不知道這樣是否合適,以及具體的實(shí)現(xiàn)感覺有點(diǎn)困難。


          最終實(shí)現(xiàn)


          完全可行,不用一行代碼。


          在線演示


          在《基于 keycloak 的關(guān)注公眾號(hào)即登錄功能的設(shè)計(jì)與實(shí)現(xiàn)》里已經(jīng)搭建了一個(gè) Keycloak 站點(diǎn):https://keycloak.jiwai.win。在這名同學(xué)的問題里,即是系統(tǒng) b。


          為了演示這名同學(xué)的系統(tǒng) a,我搭建了另一個(gè) Keycloak 站點(diǎn):https://lemur-2.cloud-iam.com/。你可以點(diǎn)擊這里,然后選擇使用系統(tǒng) b 登錄,就可以看到效果:



          顯然,Keycloak a 是一個(gè)剛部署好的 Keycloak,默認(rèn)只支持用戶名密碼登錄。但是為了使用 Keycloak b 登錄,所以又增加了一個(gè)登錄方式:UniHeart At Jiwai Win,這就是 https://keycloak.jiwai.win。選擇這個(gè)登錄方式,頁面跳轉(zhuǎn)到了 Keycloak a 的登錄界面(如果看過前面的《基于 keycloak 的關(guān)注公眾號(hào)即登錄功能的設(shè)計(jì)與實(shí)現(xiàn)》,對(duì)這個(gè)界面很熟悉了吧)。



          使用 Keycloak b 的任何登錄方式(正好這個(gè) Keycloak b 支持關(guān)注微信公眾號(hào)即登錄功能,但這個(gè)不是必須的),成功登錄后,都會(huì)回到 Keycloak a,并且是已經(jīng)登錄狀態(tài):



          雖然頁面顯示用戶沒有權(quán)限查看該頁面,但是說明登錄已經(jīng)成功。關(guān)于如何給該用戶配置相關(guān)權(quán)限,可以自行探索。

          如果已管理員賬號(hào)登錄 Keycloak a,在用戶管理界面可以看到已經(jīng)多了一個(gè) Keycloak b 中的賬號(hào):



          問題分析

          這名同學(xué)希望將兩個(gè)不同的 Keycloak realm 用戶打通,可以使用 Keycloak realm b 登錄 Keycloak realm a。或者說,使用 Keycloak b 登錄 Keycloak a,這是等價(jià)的。為了說明問題,我們不如建立兩個(gè) 2 個(gè) Keycloak 實(shí)例,不僅 realm 不同,整個(gè) Keycloak 實(shí)例都不同(數(shù)據(jù)庫也是獨(dú)立的)。


          另外,這名同學(xué)看了之前的《基于 keycloak 的關(guān)注公眾號(hào)即登錄功能的設(shè)計(jì)與實(shí)現(xiàn)》一文,可能受到微信登錄的影響。其實(shí)他這里想表達(dá)的和微信登錄沒有任何關(guān)系。


          基礎(chǔ)知識(shí)回顧


          正如前面所說,整個(gè)實(shí)現(xiàn)過程不需要一行代碼,而且配置步驟也非常簡單。但是在實(shí)施過程中,為什么會(huì)感到困難呢?很可能是需要補(bǔ)充一些基礎(chǔ)知識(shí)。這里在詳細(xì)列出實(shí)現(xiàn)步驟前,對(duì)相關(guān)知識(shí)做一個(gè)簡單回顧,從而在閱讀詳細(xì)步驟時(shí),不僅知其然,還能知其所以然。


          單點(diǎn)登錄


          Keycloak 是一個(gè)優(yōu)秀的開源的單點(diǎn)登錄工具。想使用系統(tǒng) B的用戶直接登錄系統(tǒng) A,而不用再次去系統(tǒng) A 里注冊(cè),這也是典型的單點(diǎn)登錄場景。單點(diǎn)登錄有多種協(xié)議:


          單點(diǎn)登錄認(rèn)證協(xié)議


          最知名的單點(diǎn)登錄認(rèn)證協(xié)議主要是 OpenId Connect 和 SAML。下面就來看看認(rèn)證服務(wù)器和被保護(hù)的應(yīng)用是怎么和這些協(xié)議打交道的。


          OpenId Connect


          OpenId Connect 通常簡稱為 OIDC,它是在 OAuth 2.0 的基礎(chǔ)上擴(kuò)展而成的認(rèn)證協(xié)議。OAuth 2.0 只是一個(gè)構(gòu)建認(rèn)證協(xié)議的框架,并且很不完整,但是 OIDC 確實(shí)一個(gè)羽翼豐滿的認(rèn)證與授權(quán)協(xié)議。OIDC 嚴(yán)重使用 Json Web Token(JWT)標(biāo)準(zhǔn)。這些標(biāo)準(zhǔn)用緊湊和對(duì)網(wǎng)絡(luò)友好的方式定義了 JSON 格式的唯一標(biāo)記以及對(duì)數(shù)據(jù)進(jìn)行數(shù)字化簽名和加密的方法。


          OIDC 在 Keycloak 中的使用場景分為兩種類型。第一種是應(yīng)用請(qǐng)求 Keycloak 服務(wù)器來認(rèn)證用戶。當(dāng)成功登錄后,應(yīng)用會(huì)收到一個(gè)名稱為 access_token 的唯一身份標(biāo)志符。這個(gè)唯一身份標(biāo)志符包含了諸如用戶名、電子郵箱、以及其他個(gè)人資料等等信息。access_token 會(huì)被 realm 進(jìn)行數(shù)字簽名,并且包含用戶的可訪問信息(比如用戶-角色映射),從而應(yīng)用可以使用它來決定該用戶被允許訪問應(yīng)用中的哪些資源(上面的在線演示中顯示的已登錄用戶沒有權(quán)限頁面,就是因?yàn)槟玫降?access_token 中沒有相關(guān)的可訪問信息)。


          第二種使用場景類型是客戶端想獲取遠(yuǎn)端服務(wù)的訪問權(quán)限。在這個(gè)場景下,客戶端請(qǐng)求 Keycloak 來獲取一個(gè)訪問令牌來代表用戶調(diào)用遠(yuǎn)端服務(wù)。Keycloak 認(rèn)證該用戶后詢問用戶是否同意為該客戶端授予訪問權(quán)限。一旦用戶同意授權(quán),客戶端就會(huì)收到訪問令牌。這個(gè)訪問令牌是由 realm 數(shù)字化簽名過的。該客戶端隨后就可以使用這個(gè)訪問令牌向遠(yuǎn)端服務(wù)發(fā)起 REST 調(diào)用了。這個(gè) REST 服務(wù)抽取出訪問令牌,驗(yàn)證令牌的簽名,然后基于令牌中的可訪問信息決定是否保護(hù)這個(gè)調(diào)用請(qǐng)求。


          OIDC 認(rèn)證流程


          OIDC 有多種不同的方式為客戶端或者應(yīng)用提供用戶認(rèn)證并接收身份標(biāo)記和訪問令牌。你要使用那種方式很大程度上取決于應(yīng)用或者客戶端請(qǐng)求訪問權(quán)限的類型。所有這些認(rèn)證流程都在 OIDC 和 OAuth 2.0 的規(guī)格文檔中詳細(xì)描述了,所以這里只是稍稍提及一些必要內(nèi)容。


          授權(quán)碼流程

          這是一個(gè)基于瀏覽器的協(xié)議,也是在驗(yàn)證和授權(quán)基于瀏覽器的應(yīng)用時(shí)所推薦使用的。它嚴(yán)重依賴瀏覽器重定向來獲取身份標(biāo)記與訪問令牌??偨Y(jié)如下:


          1.使用瀏覽器訪問應(yīng)用。這個(gè)應(yīng)用會(huì)提醒用戶當(dāng)前還未登錄,所以它指示瀏覽器重定向到 Keycloak 來認(rèn)證。該應(yīng)用會(huì)以查詢參數(shù)的形式在瀏覽器重定向時(shí)向 Keycloak 傳遞一個(gè)回調(diào) URL(即演示截圖中的 redirect_uri),Keycloak 在完成認(rèn)證后會(huì)使用到它。

          2.Keycloak 認(rèn)證用戶,并創(chuàng)建一次性、非常短時(shí)間有效的臨時(shí)碼。Keycloak 通過前面提供的回調(diào) URL 重定向回到應(yīng)用,同時(shí)將臨時(shí)碼作為查詢參數(shù)附加到回調(diào) URL 上。

          3.應(yīng)用抽取臨時(shí)碼,并且在后端通過不同于前端的網(wǎng)絡(luò)渠道向 Keycloak 發(fā)起 REST 調(diào)用,使用臨時(shí)碼交換身份標(biāo)記、訪問令牌以及刷新令牌。一旦這個(gè)臨時(shí)碼在獲取令牌中被使用過了,它就不能再次被使用了。這防止了潛在的重放攻擊。


          非常重要的一點(diǎn)是訪問令牌通常有效期很短,一般在分鐘級(jí)別過期。而刷新令牌由登錄協(xié)議傳送,允許應(yīng)用在訪問令牌過期后去獲取一個(gè)新的訪問令牌。這樣一個(gè)刷新協(xié)議在受損系統(tǒng)中非常重要。如果訪問令牌有效期很短,那么整個(gè)系統(tǒng)僅僅在被盜用的令牌剩余的有效期內(nèi)是處于被攻擊狀態(tài)的。如果管理員吊銷了訪問權(quán)限,那么接下來的令牌刷新請(qǐng)求會(huì)失敗。這樣更加安全并且可伸縮性更好。


          該流程另一個(gè)重要的方面是所謂的開放客戶端還是保密客戶端的概念。保密的客戶端在使用臨時(shí)碼交換令牌時(shí)需要提供客戶端密鑰。開放客戶端則不需要。只要嚴(yán)格使用 HTTPS 并且客戶端的重定向 URI 被嚴(yán)格注冊(cè),那么采用開放客戶端完全沒有問題。由于無法使用安全的方式傳輸客戶端密鑰,所以 HTML5/JavaScript 客戶端不得不天然就屬于開放客戶端。再次強(qiáng)調(diào),這僅僅在嚴(yán)格使用 HTTPS 并嚴(yán)格注冊(cè)重定向 URI 時(shí)是可以的。


          隱式流程


          這也是一個(gè)基于瀏覽器的協(xié)議,很類似授權(quán)碼流程,只是請(qǐng)求量更少,也不需要刷新令牌。該流程不被推薦,因?yàn)榇嬖谠L問令牌泄漏的可能性。比如由于令牌通過重定向 URI (詳見下)傳輸,所以可能通過瀏覽器歷史記錄泄漏。并且,由于該流程沒有為客戶端提供刷新令牌的服務(wù),所以訪問令牌不得不設(shè)置一個(gè)更長的時(shí)間,不然當(dāng)令牌失效后用戶需要再次認(rèn)證。Keycloak 不推薦這種流程但是仍然支持這種流程,因?yàn)樗嬖谟?OIDC 和 OAuth 2.0 的規(guī)格文檔中??偨Y(jié)如下:


          1.使用瀏覽器訪問應(yīng)用。應(yīng)用提示用戶當(dāng)前還未登錄,所以它指示瀏覽器重定向到 Keycloak 去認(rèn)證。應(yīng)用將回調(diào) URL (一個(gè)重定向 URI)作為查詢參數(shù)傳遞給 Keycloak,在認(rèn)證完成后會(huì)被其使用。

          2.Keycloak 認(rèn)證用戶并且創(chuàng)建身份標(biāo)記和訪問令牌。Keycloak 使用之前提供的回調(diào) URL 重定向回到應(yīng)用并使用查詢參數(shù)的方式額外添加身份標(biāo)記和訪問令牌在回調(diào) URL zhong。

          3.應(yīng)用從回調(diào) URL 中抽取身份標(biāo)記和訪問令牌。


          資源擁有者密碼憑據(jù)授權(quán)(直接訪問授權(quán))


          這在 Keycloak 管理員控制臺(tái)中指直接訪問授權(quán)。當(dāng) REST 客戶端希望代表用戶獲取令牌時(shí)使用該流程。這是一個(gè) HTTP POST 請(qǐng)求,該請(qǐng)求中包含了用戶的安全憑據(jù)和客戶端 id,以及客戶端的密鑰(如果是保密客戶端的話)。該用戶的安全憑據(jù)隨請(qǐng)求中的表單參數(shù)發(fā)送。這個(gè) HTTP 響應(yīng)中包含的身份標(biāo)記、訪問權(quán)限,以及刷新令牌。


          客戶端憑據(jù)授權(quán)

          這也是由 REST 客戶端使用的,但不是代表一個(gè)外部用戶去獲取令牌,而是基于和客戶端相關(guān)的元數(shù)據(jù)與服務(wù)賬號(hào)的權(quán)限來創(chuàng)建一個(gè)令牌。


          Keycloak 服務(wù)器的 OIDC URI 端點(diǎn)


          這一小節(jié)非常簡單,但是對(duì)本文來說,卻非常非常重要。因?yàn)樵谂渲脮r(shí),是直接要用到相關(guān)的端點(diǎn)的。

          Keycloak 會(huì)公布一系列的 OIDC 端點(diǎn)。當(dāng)你使用客戶端適配器與認(rèn)證服務(wù)器進(jìn)行 OIDC 溝通時(shí),這些 URL 非常有用。這些全部都是相對(duì) URL,且其根 URL 是使用 HTTP(S) 協(xié)議的,并且會(huì)在其 hostname 的基礎(chǔ)上添加 /auth 路徑。比如,典型的根 URL 是:https://keycloak.jiwai.win/auth,或者 http://localhost:8080/auth。


          /realms/{realm-name}/protocol/openid-connect/auth

          在授權(quán)碼流程中這個(gè) URL 端點(diǎn)用來獲取臨時(shí)碼,在隱式流程、直接授權(quán)或者客戶端授權(quán)中,這個(gè) URL 端點(diǎn)用來獲取令牌。


          /realms/{realm-name}/protocol/openid-connect/token

          這個(gè) URL 端點(diǎn)用來在授權(quán)碼流程中將臨時(shí)碼轉(zhuǎn)換成令牌。


          /realms/{realm-name}/protocol/openid-connect/logout

          這是用來執(zhí)行退出登錄操作的 URL 端點(diǎn)。


          /realms/{realm-name}/protocol/openid-connect/userinfo

          這個(gè) URL 端點(diǎn)是用來提供用戶信息服務(wù)的,其詳細(xì)描述參見 OIDC 規(guī)格說明。


          /realms/{realm-name}/protocol/openid-connect/revoke

          這個(gè) URL 端點(diǎn)用來做 OAuth 2.0 中的令牌吊銷,其詳細(xì)描述見 RFC7009


          SAML

          SAML 2.0 類似 OIDC,但是產(chǎn)生得更早并且更加成熟。由于本文使用 OIDC 解決這名知乎用戶的問題,因此不對(duì) SAML 做詳細(xì)介紹。


          OpenID Connect 和 SAML 的對(duì)比


          選擇 OpenID Connect 還是 SAML?并不推薦簡單的使用新的協(xié)議(OIDC)而不是用更老的但是更成熟的協(xié)議(SAML)這種一刀切的決策思路。


          但是 Keycloak 在大多數(shù)情況下都推薦使用 OIDC,這也是本文解決知乎網(wǎng)友問題時(shí)的做法。


          SAML 要比 OIDC 更加啰嗦一些。


          除了交換數(shù)據(jù)更加啰嗦之外,如果你仔細(xì)對(duì)比規(guī)格說明文檔,你會(huì)發(fā)現(xiàn) OIDC 是圍繞 Web 相關(guān)的工作而設(shè)計(jì)的,但是 SAML 卻是在 Web 的基礎(chǔ)上增加了新的設(shè)施。比如,相對(duì) SAML 來說,OIDC 在客戶端的實(shí)現(xiàn)更加容易,因此 OIDC 更加適合 HTML5/JavaScript 應(yīng)用。由于令牌是 JSON 格式的,他們更容易被 JavaScript 所消費(fèi)。當(dāng)然,OIDC 還有其他好特性使得在 Web 應(yīng)用中實(shí)現(xiàn)安全更加容易。比如規(guī)格文檔中提到的,使用 iframe 技巧,就很容易探測用戶是否還處于登錄狀態(tài)。


          當(dāng)然 SAML 也還是有其用武之地的。隨著 OIDC 的規(guī)格文檔的演進(jìn),你會(huì)發(fā)現(xiàn)它實(shí)現(xiàn)的越來越多的特性,早在幾年前 SAML 就已經(jīng)有了。人們一般使用 SAML 的原因是已有系統(tǒng)已經(jīng)使用了 SAML 加固,以及 SAML 更加成熟。


          集成步驟


          好了,說了這么多,是為了在后續(xù)實(shí)現(xiàn)步驟中,不迷失方向。實(shí)現(xiàn)步驟本身特別簡單,關(guān)鍵是需要了解這些基礎(chǔ)知識(shí),否則就會(huì)覺得莫名其妙。


          準(zhǔn)備工作:搭建兩個(gè) Keycloak 系統(tǒng)

          ?Keycloak b,我們將用它來登錄其他系統(tǒng),包括 Keycloak a。處于免費(fèi)的考慮,可以使用 Heroku 平臺(tái)。但是由于 Heroku 平臺(tái)的限制,不得不對(duì) Keycloak 做小的改造。改造后的 Keycloak 我放在了 Github 上:https://github.com/Jeff-Tian/keycloak-heroku,你可以點(diǎn)擊 ReadMe 中的按鈕一鍵部署到 Heroku 上。比如我部署好的 Keycloak b 是:https://keycloak.jiwai.win 。

          ?Keycloak a,你同樣可以使用 Heroku 再部署一個(gè)實(shí)例。也可以利用 https://www.cloud-iam.com/ 提供的免費(fèi)托管 Keycloak,它的限制是只能有 100 個(gè)用戶。比如我部署好的 Keycloak a 是 https://lemur-2.cloud-iam.com/。


          在 Keycloak b 中注冊(cè)一個(gè)客戶端 Keycloak a

          這很簡單,如下圖所示。關(guān)鍵配置已用紅色框圈起來。


          用 Keycloak b 的管理員賬號(hào)密碼登錄 Keycloak b,在相應(yīng)的 Realm 中點(diǎn)擊新建一個(gè)客戶端,首先需要起個(gè)名字,比如命名為 UniHeart-Cloud-IAM。


          然后需要在客戶端協(xié)議中選擇“openid-connect”。所以說基礎(chǔ)知識(shí)很重要,不然會(huì)在眾多選項(xiàng)里迷失方向。


          隨后在訪問類型中,選擇保密(如前面的基礎(chǔ)知識(shí)里講的,如果能夠保證嚴(yán)格的 HTTPS 實(shí)施以及重定向 URI 的嚴(yán)格匹配,那么選擇開放也是可以的)。


          最后,在重定向 URI 里配置好 Keycloak a 的重定向 URI(我填的是我在 Cloud IAM 中新部署的實(shí)例:https://lemur-2.cloud-iam.com/*),如果是選擇開發(fā)的訪問類型,那么這里的重定向 URI 必須一字不差。但是我這里選擇了保密的訪問類型,所以這里使用了通配符,保持靈活性。



          保存好后,切換到安全憑據(jù)面板,復(fù)制客戶端密鑰,后續(xù)步驟需要用到:



          注意在客戶端認(rèn)證中選擇第二項(xiàng):客戶端 Id 和密鑰的方式,然后復(fù)制密鑰。


          在 Keycloak a 中添加 Keycloak b 為一個(gè)身份認(rèn)證服務(wù)(idp)

          完成 Keycloak b 中的配置工作后,現(xiàn)在回到 Keycloak a,即新部署的 Cloud IAM 實(shí)例,使用 Keycloak a 的管理員賬號(hào)密碼登錄,然后點(diǎn)擊添加一個(gè)身份認(rèn)證服務(wù),選擇 Keycloak openid connect 方式:



          首先為這個(gè)身份認(rèn)證服務(wù)起個(gè)名字,比如 UniHeart At Jiwai Win



          然后的重點(diǎn)就是配置 OpenID Connect 了,基礎(chǔ)知識(shí)又派上用場。這里最重要的是把 Keycloak b 服務(wù)器的 OIDC URI 端點(diǎn)中的

          ?/realms/{realm-name}/protocol/openid-connect/auth 以及

          ?/realms/{realm-name}/protocol/openid-connect/token

          ?/realms/{realm-name}/protocol/openid-connect/userinfo 三個(gè)端點(diǎn)配置進(jìn)去:



          注意在客戶端認(rèn)證項(xiàng)里選擇以 POST 方式發(fā)送客戶端密鑰,并將 UniHeart-Cloud-IAM 填寫在客戶端 ID 中,同時(shí)將上一步復(fù)制好的密鑰粘貼進(jìn)入客戶端密鑰一欄。


          完成

          保存好就完成了。這時(shí)候點(diǎn)擊右上角,退出當(dāng)前管理員用戶,就進(jìn)入到了登錄頁面。你可以看到除了使用用戶名密碼登錄方式之外,已經(jīng)多了一個(gè)登錄選項(xiàng),這就是使用 Keycloak b 登錄:



          https://lemur-2.cloud-iam.com/auth/admin/uniheart/console/#/realms/uniheart/identity-provider-settings/provider/keycloak-oidc/uniheart-jiwai-win,這個(gè)鏈接,就是使用 Keycloak b 登錄 Keycloak a 的完整鏈接。



          瀏覽 42
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美视频手机在线观看 | 欧美精品三级网站 | 九九热这里只有精品国产的 | 狠狠久久五月 | 欧美色图亚洲色图另类 |