使用 Keycloak 配置 MinIO 进行身份验证
概述
此过程配置 MinIO 以使用 Keycloak 作为外部身份提供者 (IDP),通过 OpenID Connect (OIDC) 协议对用户进行身份验证。
此过程专门涵盖以下步骤
配置 Keycloak 以与 MinIO 身份验证和授权一起使用
配置新的或现有的 MinIO 租户以使用 Keycloak 作为 OIDC 提供者
创建策略以控制 Keycloak 认证用户的访问权限
使用 SSO 和 Keycloak 管理的身份登录 MinIO 租户控制台
使用
AssumeRoleWithWebIdentity
安全令牌服务 (STS) API 生成临时的 S3 访问凭据
此过程是针对 Keycloak 21.0.0
编写的,并经过测试。提供的说明可能适用于其他 Keycloak 版本。此过程假定您具有使用 Keycloak 的经验,并且已经查看了 其文档 以获取有关部署、配置和管理该服务的指南和最佳实践。
先决条件
MinIO Kubernetes 运算符
确保您的目标 Kubernetes 集群具有 MinIO Kubernetes 运算符的有效且正常工作的安装。此文档假定最新的稳定运算符,版本 6.0.4。
MinIO 租户
此过程假定您的 Kubernetes 集群具有足够的资源来 部署新的 MinIO 租户.
您也可以使用此步骤作为修改现有 MinIO 租户以启用 Keycloak 身份管理的指南。
Keycloak 部署和 Realm 配置
此步骤假设您已有一个 Keycloak 部署,并且您拥有其管理员访问权限。具体来说,您必须有权在 Keycloak 部署中创建和配置 Realm、客户端、客户端范围、Realm 角色、用户和组。
对于与 MinIO 租户位于同一个 Kubernetes 集群中的 Keycloak 部署,此步骤假设 Keycloak 和 MinIO Pod/服务之间可以双向访问。
对于位于 Kubernetes 集群外部的 Keycloak 部署,此步骤假设您已有一个 Ingress、负载均衡器或类似的 Kubernetes 网络控制组件来管理 MinIO 租户的网络访问。
安装并配置 mc
以访问 MinIO 集群
此步骤使用 mc
对 MinIO 集群执行操作。在具有网络访问权限的机器上安装 mc
。
您的本地主机必须能够访问 MinIO 租户,例如通过 Ingress、负载均衡器或类似的 Kubernetes 网络控制组件。
请参阅 mc
Installation Quickstart 了解有关下载和安装 mc
的说明。
此步骤假设已配置 MinIO 集群的 alias
。
配置 MinIO 以进行 Keycloak 身份管理
1) 配置或创建用于访问 Keycloak 的客户端
验证 Keycloak Administrative Console 并导航到 Clients。
选择 Create client 并按照说明为 MinIO 创建新的 Keycloak 客户端。按照以下说明填写指定的输入
Client ID |
设置为 MinIO 的唯一标识符 ( |
---|---|
Client type |
设置为 |
Always display in console |
切换到 |
Client authentication |
切换到 |
Authentication flow |
切换到 |
(可选) Authentication flow |
切换到 |
Keycloak 使用默认的一组配置值部署客户端。根据您的 Keycloak 设置和所需行为修改这些值。下表提供了一组基线设置和值来进行配置
Root URL |
设置为 |
---|---|
Home URL |
设置为您希望 MinIO 使用的 Realm ( |
Valid Redirect URI |
设置为 |
Keys -> Use JWKS URL |
切换到 |
Advanced -> Advanced Settings -> Access Token Lifespan |
设置为 |
2) 为 MinIO 客户端创建客户端范围
客户端范围允许 Keycloak 将用户属性映射为身份验证请求中返回的 JSON Web Token (JWT) 的一部分。这使得 MinIO 可以在将策略分配给用户时引用这些属性。此步骤创建支持 MinIO 授权的必要客户端范围,该授权将在 Keycloak 身份验证成功后进行。
导航到 Client scopes 视图并为 MinIO 授权创建一个新的客户端范围
Name |
设置为策略的任何可识别名称 ( |
---|---|
Include in token scope |
切换到 |
创建后,从列表中选择该范围并导航到 Mappers。
选择 Configure a new mapper 以创建一个新的映射
User Attribute |
选择 Mapper Type |
---|---|
Name |
设置为映射的任何可识别名称 ( |
User Attribute |
设置为 |
Token Claim Name |
设置为 |
Add to ID token |
设置为 |
Claim JSON Type |
设置为 |
Multivalued |
设置为 这允许在单个声明中设置多个 |
Aggregate attribute values |
设置为 这允许用户继承其组中设置的任何 |
创建后,将客户端范围分配给 MinIO 客户端。
导航到 Clients 并选择 MinIO 客户端。
选择 Client scopes,然后选择 Add client scope。
选择之前创建的范围并将 Assigned type 设置为
default
。
3) 将必要的属性应用于 Keycloak 用户/组
您必须将名为 policy
的属性分配给 Keycloak 用户或组。将值设置为 MinIO 部署上的任何 policy。
对于用户,导航到 Users 并选择或创建用户
Credentials |
如果尚未设置,请将用户密码设置为永久值 |
---|---|
Attributes |
使用键 |
对于组,导航到 Groups 并选择或创建组
Attributes |
使用键 |
---|
您可以将用户分配到组,以便他们继承指定的 policy
属性。如果您将 Mapper 设置设置为启用 Aggregate attribute values,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://keycloak-service.keycloak-namespace.svc.cluster-domain.example/realms/REALM/protocol/openid-connect/token
如果成功,access_token
将包含使用 MinIO AssumeRoleWithWebIdentity STS API 生成 S3 凭据所需的 JWT。
您可以使用 JWT 解码器查看有效负载并确保它包含键为 policy
且列出有一个或多个 MinIO 策略的值。
4) 为 Keycloak 身份验证配置 MinIO
MinIO 支持多种方法来配置 Keycloak 身份验证
使用 MinIO 租户控制台
使用终端/shell 和
mc idp openid
命令
您可以使用 MinIO 租户控制台将 Keycloak 配置为 MinIO 租户的外部身份提供者。
使用 NodePort、Ingress 或负载均衡器端点访问控制台服务。您可以使用以下命令查看控制台配置
kubectl describe svc/TENANT_NAME-console -n TENANT_NAMESPACE
将 TENANT_NAME
和 TENANT_NAMESPACE
分别替换为 MinIO 租户的名称及其命名空间。
以具有 MinIO 部署管理员权限的用户身份登录,例如具有 consoleAdmin
策略的用户。
从左侧导航栏中选择 Identity,然后选择 OpenID。选择 Create Configuration 以创建一个新的配置。
在模态框中输入以下信息
Name |
为 Keycloak 实例输入一个唯一的名称 |
---|---|
Config URL |
指定 Keycloak OpenID 配置文档的地址 (keycloak-service.keycloak-namespace.svc.cluster-domain.example) 确保 |
Client ID |
指定在步骤 1 中创建的 Keycloak 客户端的名称 |
Client Secret |
指定在步骤 1 中创建的 Keycloak 客户端的机密凭据值 |
Display Name |
指定 MinIO 控制台在配置的 Keycloak 服务的单点登录 (SSO) 工作流中显示的用户面向名称 |
Scopes |
指定要包含在 JWT 中的 OpenID 范围,例如 您可以使用支持的 OpenID 策略变量来引用这些范围,以用于程序化策略。 |
Redirect URI Dynamic |
切换到 替换客户端使用的 MinIO 控制台地址,作为 Keycloak 重定向 URI 的一部分。Keycloak 使用提供的 URI 将已验证的用户返回到控制台。 对于位于反向代理、负载均衡器或类似网络控制平面后面的 MinIO 控制台部署,您可以使用 |
选择 Save 以应用配置。
选择 Save 以应用配置。
您可以使用 mc idp openid add
命令为 Keycloak 服务创建新的配置。该命令接受所有支持的 OpenID Configuration Settings
mc idp openid add ALIAS PRIMARY_IAM \
client_id=MINIO_CLIENT \
client_secret=MINIO_CLIENT_SECRET \
config_url="https://keycloak-service.keycloak-namespace.svc.cluster-domain.example/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 配置文档的地址 (keycloak-service.keycloak-namespace.svc.cluster-domain.example) |
|
将 MinIO 控制台在配置的 Keycloak 服务的单点登录 (SSO) 工作流中显示的用户界面名称设置为 |
|
设置为要在 JWT 中包含的 OpenID 作用域列表,例如 |
|
设置为 替换客户端使用的 MinIO 控制台地址,作为 Keycloak 重定向 URI 的一部分。Keycloak 使用提供的 URI 将已验证的用户返回到控制台。 对于位于反向代理、负载均衡器或类似网络控制平面后面的 MinIO 控制台部署,您可以使用 |
重新启动 MinIO 部署以使更改生效。
检查 MinIO 日志并验证启动是否成功,没有与 OIDC 配置相关的错误。
如果您尝试使用控制台登录,现在应该会看到一个使用配置的 显示名称 的 (SSO) 按钮。
指定一个配置的用户并尝试登录。MinIO 应该会自动将您重定向到 Keycloak 登录条目。成功身份验证后,Keycloak 应该会将您重定向回 MinIO 控制台,使用的是原始控制台 URL 或 如果配置了,则使用 重定向 URI。
5) 使用安全令牌服务 (STS) 生成应用程序凭据
使用 S3 兼容 SDK 的应用程序必须以访问密钥和密钥形式指定凭据。MinIO AssumeRoleWithWebIdentity API 使用 Keycloak 在身份验证后返回的 JWT 返回必要的临时凭据,包括所需的会话令牌。
您可以使用以下 HTTP 调用序列和 curl
实用程序来测试此工作流
以 Keycloak 用户身份进行身份验证并检索 JWT 令牌
curl -X POST "https://keycloak-service.keycloak-namespace.svc.cluster-domain.example/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://minio.minio-tenant.svc.cluster-domain.example" \ -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( "minio.minio-tenant.svc.cluster-domain.example", access_key = "ACCESS_KEY", secret_key = "SECRET_KEY", session_token = "SESSION_TOKEN" secure = True ) client.list_buckets()
下一步
应用程序应该使用其选择的 SDK 实现 STS AssumeRoleWithWebIdentity 流。当 STS 凭据过期时,应用程序应该在重新生成 JWT 令牌、STS 令牌和 MinIO 凭据之前,在重新尝试和继续操作之前,实现逻辑。
或者,用户可以使用 MinIO 控制台生成 访问密钥,以便使用其 Keycloak 凭据创建长期 API 密钥类型的访问。
启用 Keycloak 管理 REST API
MinIO 支持使用 Keycloak 管理 REST API 检查经过身份验证的用户是否存在以及是否在 Keycloak 领域中启用。此功能允许 MinIO 更快地撤销以前经过身份验证的 Keycloak 用户的访问权限。没有此功能,MinIO 可以禁用已禁用或已删除用户的访问权限的最早时间点是最后检索到的身份验证令牌过期时。
此过程假设使用 Keycloak 作为外部身份管理器的现有 MinIO 部署。
1) 创建必要的客户端作用域
导航到 客户端作用域 视图并创建一个新作用域
Name |
设置为作用域的可识别名称 ( |
---|---|
映射器 |
选择 配置新的映射器 |
受众 |
将 名称 设置为映射的可识别名称 ( |
包含的客户端受众 |
设置为 |
导航到 客户端 并选择 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 领域名称
在适当的配置位置(例如 /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 领域名称