背景
在支持Keycloak第三方認(rèn)證,同時(shí)需要從keycloak中獲取到用戶(員工)的部門(group)信息,以便于Jenkins針對(duì)不同的部門(group)進(jìn)行權(quán)限控制。
因此前提是要飛書把用戶的部門信息同步到Keycloak上。我們通過訂閱飛書的用戶、部門相關(guān)事件,開發(fā)了一個(gè)adapter程序,在接收到飛書事件后,調(diào)用一堆飛書API和Keycloak API實(shí)現(xiàn)了飛書和Keycloak的部門信息同步,從而使得飛書中用戶與部門的增刪改事件可以(實(shí)時(shí))同步到Keycloak中。
其中Keycloak與飛書的集成可以參考:https://github.com/tedgxt/keycloak-service-social-lark
Jenkins配置前必看
-
Configure Global Security
中Authorization
配置為Anyone can do anything
。防止切換到oidc登陸時(shí),若不成功無(wú)法登陸Jenkins。設(shè)置了此項(xiàng)后即使未登錄Jenkins也能修改配置(生產(chǎn)環(huán)境操作時(shí)注意安全性)。 - 后臺(tái)備份Jenkins的
config.xml
文件,以便于配置過程異常時(shí)的恢復(fù)。
Keycloak配置
- 創(chuàng)建Jenkins使用的client,此處命名為
jenkins-test
,類型選擇oidc。jenkins-test
就是后面Jenkins中要配置的Client ID
。 - client詳情中, 設(shè)置
Access Type
為confidential
,并設(shè)置Valid Redirect URIs
為允許跳轉(zhuǎn)的Jenkins地址。記錄Credentials標(biāo)簽頁(yè)中的Secret,后面在Jenkins配置Client Secret
時(shí)使用。 - 配置使得Keycloak可以提供group信息。有兩種配置方式,按下面的說明根據(jù)實(shí)際場(chǎng)景選擇其中一種進(jìn)行配置:
- 點(diǎn)擊client
jenkins-test
,進(jìn)入設(shè)置頁(yè),選擇Mappers
,右上角點(diǎn)擊create。添加group相關(guān)映射,Mapper Type選擇Group Membership
,Token Claim Name
配置為group-membership
,其中Token Claim Name
的值就是jwt token中g(shù)roup信息的key值,后面Jenkins會(huì)通過該key獲取到group信息。該方法是針對(duì)單個(gè)client。配置如下圖:
image.png - 點(diǎn)擊
Client Scopes
->profile
->Mappers
,Token Claim Name
配置為group-membership
,Mapper Type
設(shè)置為Group Membership
。注意該方法會(huì)導(dǎo)致所有的client的profile信息都包含group信息。
配置如下圖
image.png
配置了group相關(guān)映射后,調(diào)用Keycloak的接口可以獲取基于用戶的Jwt Token,通過解析Jwt Token可以獲取到group-membership信息:
// 省略了token payload信息
"scope": "email profile",
"email_verified": false,
"name": "xxxx",
"nickname": "xxxx",
"preferred_username": "xiatao.guan@xxxxxx",
"given_name": "xxxx",
"family_name": "xxxxx",
"email": "xiatao.guan@xxxxxx",
"group-membership": [
"/Dev/HZ Dev/Ops & QA& LBware/QA"
后續(xù)Jenkins通過配置,會(huì)從token的group-membership
中獲取用戶的group信息。
Jenkins配置
安裝OIDC插件
當(dāng)前Jenkins實(shí)際有提供Keycloak插件用于直接對(duì)接Keycloak。有配置成功過的同學(xué)可以留言交流一下。
當(dāng)前我們使用OIDC插件來(lái)進(jìn)行配置。
需要配置信息如下:
配置項(xiàng) | 值 | 描述 |
---|---|---|
Client id | jenkins-test | Keycloak中添加的jenkins client的Client ID |
Client secret | xxxxx | Keycloak中添加的jenkins client的Secret |
Token Server url | xxxxx | 獲取token的地址 |
Authorization server url | xxxxx | 授權(quán)地址 |
UserInfo server url | xxxxx | 獲取用戶信息的地址 |
Scopes | openid email phone group-membership等 | 一定要包含group-membership,否則無(wú)法獲取到group信息 |
User name field name | 使用email作為jenkins用戶名 | |
Full name field name | 使用email作為jenkins用戶全名 | |
Email field name | ||
Groups field name | group-membership | Keycloak中配置的group的映射名 |
保存后退出當(dāng)前用戶,重新登陸Jenkins會(huì)跳轉(zhuǎn)到Keycloak的登陸頁(yè)面。我們?cè)贙eycloak中集成了飛書,通過飛書掃碼登錄后即跳轉(zhuǎn)到Jenkins主頁(yè)。
進(jìn)入用戶詳情頁(yè),若當(dāng)前用戶有管理員權(quán)限,可以看到Groups信息,如下圖:
若只是普通用戶,在用戶詳情頁(yè)看不到Groups信息,可以訪問 http://127.0.0.1:8280/whoAmI/ 獲取到當(dāng)前登陸用戶的Groups信息,如圖:
后面就可以通過配置Jenkins的授權(quán)策略,來(lái)實(shí)現(xiàn)基于group的權(quán)限管理啦。
Trobule Shotting
- 在生產(chǎn)環(huán)境Jenkins接入keycloak,在Keycloak/飛書登陸后,Jenkins跳轉(zhuǎn)后頁(yè)面報(bào)401錯(cuò)誤
/securityRealm/finishLogin 401
。檢查對(duì)比了Keycloak和Jenkins線上與線下環(huán)境相關(guān)的配置,發(fā)現(xiàn)配置都是相同的。
經(jīng)過分析HTTP請(qǐng)求,發(fā)現(xiàn)線上環(huán)境的Jenkins對(duì)外暴露的是域名https://jenkins.xxxxx.com/
,而認(rèn)證后跳轉(zhuǎn)到的401地址是http://10.xx.xx.xx:8080/securityRealm/finishLogin
。
http://10.xx.xx.xx:8080
是Jenkins的ip訪問地址,并且通過該IP訪問方式,Keycloak/飛書可以成功登陸并跳轉(zhuǎn)到Jenkins頁(yè)面。
檢查Jenkins的配置,發(fā)現(xiàn)Jenkins URL
被配置成了http://10.xx.xx.xx:8080
,導(dǎo)致通過域名方式訪問Jenkins并認(rèn)證后,跳轉(zhuǎn)到了http://10.xx.xx.xx:8080
,此處應(yīng)該是存在session問題,導(dǎo)致認(rèn)證失敗報(bào)401錯(cuò)誤。于是把Jenkins URL
改為域名https://jenkins.xxxxx.com/
,生效后通過域名登陸成功。