使用 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 集群的 alias
。
为 Keycloak 身份管理配置 MinIO
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 容器存储数据的空文件夹的路径。
或者,您可以将容器部署为根用户,以允许访问主机网络以进行容器间网络通信。
本教程不涉及通过 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 在将策略分配给用户时引用这些属性。此步骤创建支持 MinIO 授权的必要客户端范围,前提是 Keycloak 身份验证成功。
导航到 客户端范围 视图并为 MinIO 授权创建一个新的客户端范围
姓名 |
设置为策略的任何可识别名称 ( |
---|---|
包含在令牌范围内 |
切换到 |
创建后,从列表中选择范围并导航到 映射器。
选择 配置新的映射器 以创建新的映射
用户属性 |
选择映射器类型 |
---|---|
姓名 |
设置为映射的任何可识别名称 ( |
用户属性 |
设置为 |
令牌声明名称 |
设置为 |
添加到 ID 令牌 |
设置为 |
声明 JSON 类型 |
设置为 |
多值 |
设置为 这允许在单个声明中设置多个 |
聚合属性值 |
设置为 这允许用户继承其组中设置的任何 |
创建后,将客户端范围分配给 MinIO 客户端。
导航到 客户端 并选择 MinIO 客户端。
选择 客户端范围,然后选择 添加客户端范围。
选择之前创建的范围并将 已分配类型 设置为
default
。
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" \
http://127.0.0.1:8080/realms/REALM/protocol/openid-connect/token
如果成功,access_token
包含使用 MinIO AssumeRoleWithWebIdentity STS API 生成 S3 凭据所需的 JWT。
您可以使用 JWT 解码器查看有效负载并确保它包含 policy
键,其中列出了一个或多个 MinIO 策略。
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) 为 Keycloak 身份验证配置 MinIO
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 动态 |
切换到 替换客户端用作 Keycloak 重定向 URI 的一部分的 MinIO 控制台地址。Keycloak 使用提供的 URI 将已验证的用户返回到控制台。 对于位于反向代理、负载均衡器或类似网络控制平面后面的 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="http://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 范围列表,例如 |
|
设置为 替换客户端用作 Keycloak 重定向 URI 的一部分的 MinIO 控制台地址。Keycloak 使用提供的 URI 将已验证的用户返回到控制台。 对于位于反向代理、负载均衡器或类似网络控制平面后面的 MinIO 控制台部署,您可以改为使用 |
在使用 -e ENVVAR=VALUE
标志启动容器之前,设置以下 环境变量。
以下示例代码设置了与将 Keycloak 配置为外部身份管理提供商相关的最小必需环境变量。
MINIO_IDENTITY_OPENID_CONFIG_URL_PRIMARY_IAM="http://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 范围,例如 |
|
设置为 替换客户端用作 Keycloak 重定向 URI 的一部分的 MinIO 控制台地址。Keycloak 使用提供的 URI 将已验证的用户返回到控制台。 对于位于反向代理、负载均衡器或类似网络控制平面后面的 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 "http://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 "http://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()
后续步骤
应用程序应该使用他们选择的 STS 流来实现 SDK。当 STS 凭据过期时,应用程序应该在适当位置实现逻辑以在重试和继续操作之前重新生成 JWT 令牌、STS 令牌和 MinIO 凭据。
或者,用户可以通过 MinIO 控制台生成 访问密钥,以使用他们的 Keycloak 凭据创建长期有效的 API 密钥式访问。
启用 Keycloak 管理 REST API
MinIO 支持使用 Keycloak 管理 REST API 来检查经过身份验证的用户是否 *存在* 并且已在 Keycloak realm 上启用。此功能允许 MinIO 更快地从以前经过身份验证的 Keycloak 用户中删除访问权限。如果没有此功能,MinIO 可以禁用已停用或已删除用户的访问权限的最早时间点是在最后检索到的身份验证令牌过期时。
此过程假定已存在使用 Keycloak 作为外部身份管理器的 MinIO 部署。
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 名称。