使用 Keycloak 設定 MinIO 進行身份驗證
概觀
此程序設定 MinIO 使用 Keycloak 作為外部身分提供者 (IDP),透過 OpenID Connect (OIDC) 協定驗證使用者身分。
此程序具體涵蓋以下步驟
部署 Keycloak 和 MinIO 容器
設定 Keycloak 以搭配 MinIO 身份驗證和授權使用
設定 MinIO 以使用 Keycloak 作為 OIDC 提供者
建立策略以控制 Keycloak 驗證使用者的存取
使用 SSO 和 Keycloak 管理的身分登入 MinIO 主控台
使用
AssumeRoleWithWebIdentity
安全權杖服務 (STS) API 產生暫時的 S3 存取憑證
此程序是根據 Keycloak 21.0.0
編寫和測試的。所提供的說明可能適用於其他 Keycloak 版本。此程序假設您具有 Keycloak 的先前經驗,並且已檢閱其文件,以獲取有關部署、設定和管理服務的指導和最佳實務。
先決條件
MinIO 部署
此程序假設現有的 MinIO 叢集執行 最新的穩定 MinIO 版本。請參閱安裝和部署 MinIO,以取得有關新 MinIO 部署的更完整文件。
此程序*可能*適用於舊版本的 MinIO。
安裝和設定 mc
以存取 MinIO 叢集
此程序使用 mc
在 MinIO 叢集上執行操作。在可以網路存取叢集的機器上安裝 mc
。
請參閱 mc
的 安裝快速入門,以取得下載和安裝 mc
的說明。
此程序假設您已為 MinIO 叢集設定 別名
。
設定 MinIO 以進行 Keycloak 身分管理
1) 建立 Podman Pod
建立一個 Podman Pod,以在具有共享網路的 Pod 中部署 Keycloak 和 MinIO 容器。這可確保兩個容器可以正常通訊。
podman pod create \
-p 9000:9000 -p 9001:9001 -p 8080:8080 \
-v ~/minio-keycloak/minio:/mnt/minio \
-n minio-keycloak
將 ~/minio-keycloak/minio
替換為 MinIO 容器儲存資料的空資料夾路徑。
您也可以選擇以 Root 身分部署容器,以便存取主機網路以進行容器間網路連線。
透過 Docker Compose 部署超出本教學範圍。
2) 啟動 Keycloak 容器
請按照 在容器中執行 Keycloak 的說明進行操作。 在開發模式中嘗試 Keycloak 的步驟足以滿足此程序的需求。
podman run -dt \
--name keycloak \
--pod minio-keycloak \
-e KEYCLOAK_ADMIN=keycloakadmin \
-e KEYCLOAK_ADMIN_PASSWORD=keycloakadmin123 \
quay.io/keycloak/keycloak:latest start-dev
前往 localhost:8080
以存取 Keycloak 容器。
3) 設定或建立用戶端以存取 Keycloak
驗證至 Keycloak 的管理主控台並導覽至用戶端。
選擇建立用戶端並按照說明為 MinIO 建立新的 Keycloak 用戶端。填寫指定的輸入,如下所示
用戶端 ID |
設定為 MinIO 的唯一識別碼 ( |
---|---|
用戶端類型 |
設定為 |
永遠顯示在主控台中 |
切換至 |
用戶端驗證 |
切換至 |
驗證流程 |
開啟 |
(選用) 驗證流程 |
開啟 |
Keycloak 會部署具有一組預設設定值的用戶端。根據您的 Keycloak 設定和所需行為修改這些值。下表提供設定和值的基準
根 URL |
設定為 |
---|---|
首頁 URL |
設定為您希望 MinIO 使用的 Realm ( |
有效重新導向 URI |
設定為 |
金鑰 -> 使用 JWKS URL |
切換至 |
進階 -> 進階設定 -> 存取權杖存留時間 |
設定為 |
4) 為 MinIO 用戶端建立用戶端範圍
用戶端範圍允許 Keycloak 將使用者屬性對應為驗證請求中傳回的 JSON Web 權杖 (JWT) 的一部分。這允許 MinIO 在將原則指派給使用者時參考這些屬性。此步驟建立必要的用戶端範圍,以在 Keycloak 驗證成功後支援 MinIO 授權。
導覽至用戶端範圍檢視並為 MinIO 授權建立新的用戶端範圍
名稱 |
設定為任何可識別的原則名稱 ( |
---|---|
包含在權杖範圍中 |
切換至 |
建立後,從清單中選擇範圍,然後導覽至對應器。
選擇設定新的對應器以建立新的對應
使用者屬性 |
選擇對應器類型 |
---|---|
名稱 |
設定為任何可識別的對應名稱 ( |
使用者屬性 |
設定為 |
權杖宣告名稱 |
設定為 |
新增至 ID 權杖 |
設定為 |
宣告 JSON 類型 |
設定為 |
多值 |
設定為 這允許在單一宣告中設定多個 |
彙總屬性值 |
設定為 這允許使用者繼承其群組中設定的任何 |
建立後,將用戶端範圍指派給 MinIO 用戶端。
導覽至用戶端並選擇 MinIO 用戶端。
選擇用戶端範圍,然後選擇新增用戶端範圍。
選擇先前建立的範圍,並將指派的類型設定為
預設
。
5) 將必要的屬性套用至 Keycloak 使用者/群組
您必須將名為 policy
的屬性指派給 Keycloak 使用者或群組。將值設定為 MinIO 部署上的任何 原則。
對於使用者,導覽至使用者並選擇或建立使用者
認證 |
如果尚未設定,請將使用者密碼設定為永久值 |
---|---|
屬性 |
建立新的屬性,其中索引鍵為 |
對於群組,導覽至群組並選擇或建立群組
屬性 |
建立新的屬性,其中索引鍵為 |
---|
您可以將使用者指派給群組,以便他們繼承指定的 policy
屬性。如果您將對應器設定設定為啟用彙總屬性值,Keycloak 會將原則的彙總陣列包含在經過驗證的使用者 JWT 權杖中。MinIO 可以在授權使用者時使用此原則清單。
您可以使用 Keycloak API 測試使用者的設定原則
curl -d "client_id=minio" \
-d "client_secret=secretvalue" \
-d "grant_type=password" \
-d "username=minio-user-1" \
-d "password=minio-user-1-password" \
https://127.0.0.1:8080/realms/REALM/protocol/openid-connect/token
如果成功,access_token
包含使用 MinIO AssumeRoleWithWebIdentity STS API 並產生 S3 認證所需的 JWT。
您可以使用 JWT 解碼器來檢閱承載,並確保它包含列出一個或多個 MinIO 原則的 policy
金鑰。
6) 啟動 MinIO 容器
下列命令會啟動 MinIO 容器並將其附加到 minio-keycloak
pod。
podman run -dt \
--name minio-server \
--pod minio-keycloak \
quay.io/minio/minio:RELEASE.2023-02-22T18-23-45Z server /mnt/data --console-address :9001
前往 localhost:9001
以存取 MinIO 主控台。使用預設認證 minioadmin:minioadmin
登入。
7) 設定 MinIO 以進行 Keycloak 驗證
MinIO 支援多種方法來設定 Keycloak 驗證
使用 MinIO 主控台
使用終端機/Shell 和
mc idp openid
命令使用在啟動 MinIO 之前設定的環境變數
以具有 MinIO 部署管理員權限的使用者身分登入,例如具有 consoleAdmin
原則的使用者。
從左側導覽列中選擇身分,然後選擇OpenID。選擇建立組態以建立新的組態。
在模式中輸入以下資訊
名稱 |
輸入 Keycloak 執行個體的唯一名稱 |
---|---|
組態 URL |
指定 Keycloak OpenID 組態文件的位址 (localhost:8080) 確保 |
用戶端 ID |
指定在步驟 1 中建立的 Keycloak 用戶端名稱 |
用戶端密碼 |
指定在步驟 1 中建立的 Keycloak 用戶端的密碼憑證值 |
顯示名稱 |
指定 MinIO 主控台在已設定 Keycloak 服務的單一登入 (SSO) 工作流程中顯示的使用者面向名稱 |
範圍 |
指定要包含在 JWT 中的 OpenID 範圍,例如 您可以出於程式設計原則的目的,使用支援的 OpenID 原則變數來參考這些範圍。 |
重新導向 URI 動態 |
切換至 取代用戶端使用的 MinIO 主控台位址,作為 Keycloak 重新導向 URI 的一部分。Keycloak 使用提供的 URI 將經過驗證的使用者傳回主控台。 對於反向 Proxy、負載平衡器或類似網路控制平面後方的 MinIO 主控台部署,您可以改用 |
選擇儲存以套用組態。
您可以使用 mc idp openid add
命令來為 Keycloak 服務建立新的組態。此命令會接受所有支援的 OpenID 組態設定
mc idp openid add ALIAS PRIMARY_IAM \
client_id=MINIO_CLIENT \
client_secret=MINIO_CLIENT_SECRET \
config_url="https://127.0.0.1:8080/realms/REALM/.well-known/openid-configuration" \
display_name="SSO_IDENTIFIER"
scopes="openid,email,preferred_username" \
redirect_uri_dynamic="on"
|
設定為 Keycloak 服務的唯一識別碼,例如 |
---|---|
MINIO_CLIENT MINIO_CLIENT_SECRET |
設定為步驟 1 中設定的 Keycloak 用戶端 ID 和密碼 |
|
設定為 Keycloak OpenID 組態文件的位址 (localhost:8080) |
|
設定為 MinIO 主控台在已設定 Keycloak 服務的單一登入 (SSO) 工作流程中顯示的使用者面向名稱 |
|
設定為您想要包含在 JWT 中的 OpenID 範圍清單,例如 |
|
設定為 取代用戶端使用的 MinIO 主控台位址,作為 Keycloak 重新導向 URI 的一部分。Keycloak 使用提供的 URI 將經過驗證的使用者傳回主控台。 對於反向 Proxy、負載平衡器或類似網路控制平面後方的 MinIO 主控台部署,您可以改用 |
在啟動容器之前,請先使用 -e ENVVAR=VALUE
標誌設定下列環境變數。
以下範例程式碼設定了將 Keycloak 配置為外部身分管理供應商所需的最低限度環境變數。
MINIO_IDENTITY_OPENID_CONFIG_URL_PRIMARY_IAM="https://127.0.0.1:8080/.well-known/openid-configuration"
MINIO_IDENTITY_OPENID_CLIENT_ID_PRIMARY_IAM="MINIO_CLIENT"
MINIO_IDENTITY_OPENID_CLIENT_SECRET_PRIMARY_IAM="MINIO_CLIENT_SECRET"
MINIO_IDENTITY_OPENID_DISPLAY_NAME_PRIMARY_IAM="SSO_IDENTIFIER"
MINIO_IDENTITY_OPENID_SCOPES_PRIMARY_IAM="openid,email,preferred_username"
MINIO_IDENTITY_OPENID_REDIRECT_URI_DYNAMIC_PRIMARY_IAM="on"
|
將後綴 如果您打算僅為部署配置單一 OIDC 供應商,則可以省略後綴。 |
---|---|
指定 Keycloak OpenID 組態文件的位址 (localhost:8080) 請確保 |
|
指定在步驟 1 中設定的 Keycloak 用戶端 ID 和密碼。 |
|
指定 MinIO 主控台在已設定 Keycloak 服務的單一登入 (SSO) 工作流程中顯示的使用者面向名稱 |
|
指定您要包含在 JWT 中的 OpenID 範圍,例如 |
|
設定為 取代用戶端使用的 MinIO 主控台位址,作為 Keycloak 重新導向 URI 的一部分。Keycloak 使用提供的 URI 將經過驗證的使用者傳回主控台。 對於反向 Proxy、負載平衡器或類似網路控制平面後方的 MinIO 主控台部署,您可以改用 |
如需這些變數的完整文件,請參閱 OpenID 身分管理設定。
您必須重新啟動 MinIO 部署,變更才會生效。
檢查 MinIO 伺服器記錄,並確認啟動成功且沒有與 Keycloak 設定相關的錯誤。
如果您嘗試使用主控台登入,現在應該會看到一個使用已設定顯示名稱的 (SSO) 按鈕。
指定一個已設定的使用者並嘗試登入。MinIO 應該會自動將您重新導向至 Keycloak 登入頁面。成功驗證後,Keycloak 應該會將您重新導向回 MinIO 主控台。
8) 使用安全性權杖服務 (STS) 產生應用程式憑證
使用相容於 S3 的 SDK 的應用程式必須以存取金鑰和密碼金鑰的形式指定憑證。MinIO AssumeRoleWithWebIdentity API 會返回必要的暫時憑證,包括在驗證後由 Keycloak 返回的 JWT 使用所需的會話權杖。
您可以使用下列 HTTP 呼叫序列和 curl
工具來測試此工作流程。
以 Keycloak 使用者身分驗證並擷取 JWT 權杖。
curl -X POST "https://127.0.0.1:8080/realms/REALM/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=USER" \ -d "password=PASSWORD" \ -d "grant_type=password" \ -d "client_id=CLIENT" \ -d "client_secret=SECRET"
將
USER
和PASSWORD
替換為REALM
上 Keycloak 使用者的憑證。將
CLIENT
和SECRET
替換為REALM
上 MinIO 特定 Keycloak 用戶端的用戶端 ID 和密碼。
您可以使用
jq
或類似的 JSON 格式化工具來處理結果。擷取access_token
欄位以擷取必要的存取權杖。請注意expires_in
欄位,以注意權杖過期前的秒數。使用
AssumeRoleWithWebIdentity
API 產生 MinIO 憑證curl -X POST "https://127.0.0.1:9000" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "Action=AssumeRoleWithWebIdentity" \ -d "Version=2011-06-15" \ -d "DurationSeconds=86000" \ -d "WebIdentityToken=TOKEN"
將
TOKEN
替換為 Keycloak 返回的access_token
值。API 成功時會傳回包含下列金鑰的 XML 文件
Credentials.AccessKeyId
- Keycloak 使用者的存取金鑰Credentials.SecretAccessKey
- Keycloak 使用者的密碼金鑰Credentials.SessionToken
- Keycloak 使用者的會話權杖Credentials.Expiration
- 產生的憑證的到期日
測試憑證
使用您偏好的相容於 S3 的 SDK,使用產生的憑證連線到 MinIO。
例如,下列使用 MinIO Python SDK 的 Python 程式碼會連線到 MinIO 部署並傳回儲存貯體清單
from minio import Minio client = MinIO( "localhost:9000", access_key = "ACCESS_KEY", secret_key = "SECRET_KEY", session_token = "SESSION_TOKEN" secure = True ) client.list_buckets()
後續步驟
應用程式應該使用其選擇的 SDK 來實作 STS 流程。當 STS 憑證過期時,應用程式應具備邏輯,以在重試和繼續操作之前重新產生 JWT 權杖、STS 權杖和 MinIO 憑證。
或者,使用者可以使用其 Keycloak 憑證,透過 MinIO 主控台產生存取金鑰,以建立類似 API 金鑰的長期存取。
啟用 Keycloak 管理 REST API
MinIO 支援使用 Keycloak 管理 REST API 來檢查已驗證的使用者是否存在且在 Keycloak Realm 上啟用。此功能可讓 MinIO 更快速地移除先前驗證過的 Keycloak 使用者的存取權。如果沒有此功能,MinIO 可以停用已停用或移除的使用者存取權的最早時間點是最後擷取的驗證權杖過期時。
此程序假設現有的 MinIO 部署已設定 Keycloak 作為外部身分管理員。
1) 建立必要的用戶端範圍
導覽至 用戶端範圍檢視並建立新的範圍
名稱 |
將範圍設定為可識別的名稱 ( |
---|---|
對應器 |
選取設定新的對應器 |
對象 |
將名稱設定為對應的任何可識別名稱 ( |
包含的用戶端對象 |
設定為 |
導覽至用戶端並選取 MinIO 用戶端
從服務帳戶角色,選取指派角色並指派
admin
角色從 用戶端範圍,選取新增用戶端範圍並新增先前建立的範圍
導覽至 設定並確保驗證流程包括 服務 帳戶 角色
。
2) 驗證管理 API 存取
您可以使用 MinIO 用戶端憑證搭配管理 REST API 來擷取持有人權杖和使用者資料,藉此驗證此功能
擷取持有人權杖
curl -d "client_id=minio" \ -d "client_secret=secretvalue" \ -d "grant_type=password" \ http://keycloak-url:port/admin/realms/REALM/protocol/openid-connect/token
使用傳回的值作為
access_token
來存取管理 APIcurl -H "Authentication: Bearer ACCESS_TOKEN_VALUE" \ http://keycloak-url:port/admin/realms/REALM/users/UUID
將
UUID
替換為您要擷取的使用者的唯一 ID。回應應類似如下{ "id": "954de141-781b-4eaf-81bf-bf3751cdc5f2", "createdTimestamp": 1675866684976, "username": "minio-user-1", "enabled": true, "totp": false, "emailVerified": false, "firstName": "", "lastName": "", "attributes": { "policy": [ "readWrite" ] }, "disableableCredentialTypes": [], "requiredActions": [], "notBefore": 0, "access": { "manageGroupMembership": true, "view": true, "mapRoles": true, "impersonate": true, "manage": true } }
如果傳回的值具有
enabled: false
或null
(使用者已從 Keycloak 移除),則 MinIO 將撤銷已驗證的使用者的存取權。
3) 在 MinIO 上啟用 Keycloak 管理支援
MinIO 支援多種設定 Keycloak 管理 API 支援的方法
使用終端機/Shell 和
mc idp openid
命令使用在啟動 MinIO 之前設定的環境變數
您可以使用 mc idp openid update
命令來修改現有 Keycloak 服務的設定。您也可以在首次設定 Keycloak 時加入以下設定。此命令會採用所有支援的 OpenID 設定
mc idp openid update ALIAS KEYCLOAK_IDENTIFIER \
vendor="keycloak" \
keycloak_admin_url="https://keycloak-url:port/admin"
keycloak_realm="REALM"
將
KEYCLOAK_IDENTIFIER
替換為已設定的 Keycloak IDP 名稱。您可以使用mc idp openid ls
來檢視 MinIO 部署上所有已設定的 IDP 設定在
keycloak_admin_url
設定中指定 Keycloak 管理 URL在
keycloak_realm
中指定 Keycloak Realm 名稱
在適當的設定位置 (例如 /etc/default/minio
) 中設定下列環境變數。
以下範例程式碼設定了與為現有 Keycloak 設定啟用 Keycloak 管理 API 相關的最低限度環境變數。將後綴 _PRIMARY_IAM
替換為目標 Keycloak 設定的唯一識別符。
MINIO_IDENTITY_OPENID_VENDOR_PRIMARY_IAM="keycloak"
MINIO_IDENTITY_OPENID_KEYCLOAK_ADMIN_URL_PRIMARY_IAM="https://keycloak-url:port/admin"
MINIO_IDENTITY_OPENID_KEYCLOAK_REALM_PRIMARY_IAM="REALM"
在
MINIO_IDENTITY_OPENID_KEYCLOAK_ADMIN_URL
中指定 Keycloak 管理 URL在
MINIO_IDENTITY_OPENID_KEYCLOAK_REALM
中指定 Keycloak Realm 名稱