文档

使用 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 的说明,请参阅 mc安装快速入门

此过程假设已为 MinIO 集群配置了 别名

为 MinIO 配置 Keycloak 身份管理

1) 配置或创建访问 Keycloak 的客户端

登录 Keycloak 的 管理控制台 并导航到 客户端

选择 创建客户端 并按照说明为 MinIO 创建一个新的 Keycloak 客户端。填写以下指定的输入内容

客户端 ID

设置为 MinIO 的唯一标识符 (minio)

客户端类型

设置为 OpenID Connect

始终在控制台中显示

切换到

客户端认证

切换到

认证流程

打开 标准 流程

(可选) 认证流程

打开 直接 访问 授权 (API 测试)

Keycloak 会使用一组默认的配置值部署客户端。根据您的 Keycloak 设置和所需行为修改这些值。下表提供了要配置的设置和值的基线

根 URL

设置为 ${authBaseUrl}

主页 URL

设置为您希望 MinIO 使用的 Realm (/realms/master/account/)

有效的重定向 URI

设置为 *

密钥 -> 使用 JWKS URL

切换到

高级 -> 高级设置 -> 访问令牌有效期

设置为 1 小时

2) 为 MinIO 客户端创建客户端作用域

客户端作用域允许 Keycloak 将用户属性作为 JSON Web 令牌 (JWT) 的一部分映射到认证请求中返回的 JWT 中。这允许 MinIO 在将策略分配给用户时引用这些属性。此步骤创建支持 MinIO 认证成功后 MinIO 授权的必要客户端作用域。

导航到 客户端作用域 视图并为 MinIO 授权创建一个新的客户端作用域

名称

设置为策略的任何可识别名称 (minio-authorization)

包含在令牌作用域中

切换到

创建后,从列表中选择作用域并导航到 映射器

选择 配置新的映射器 以创建新的映射

用户属性

选择映射器类型

名称

设置为映射的任何可识别名称 (minio-policy-mapper)

用户属性

设置为 policy

令牌声明名称

设置为 policy

添加到 ID 令牌

设置为

声明 JSON 类型

设置为 字符串

多值

设置为

这允许在单个声明中设置多个 policy 值。

聚合属性值

设置为

这允许用户继承其组中设置的任何 policy

创建后,将客户端作用域分配给 MinIO 客户端。

  1. 导航到 客户端 并选择 MinIO 客户端。

  2. 选择 客户端作用域,然后选择 添加客户端作用域

  3. 选择先前创建的作用域并将 分配类型 设置为 default

3) 将必要的属性应用于 Keycloak 用户/组

您必须将名为 policy 的属性分配给 Keycloak 用户或组。将值设置为 MinIO 部署上的任何 策略

对于用户,导航到 用户 并选择或创建用户

凭据

如果尚未设置,请将用户密码设置为永久值

属性

创建一个新的属性,键为 policy,值为任何 策略 (consoleAdmin)

对于组,导航到 并选择或创建组

属性

创建一个新的属性,键为 policy,值为任何 策略 (consoleAdmin)

您可以将用户分配到组,以便他们继承指定的 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://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) 为 MinIO 配置 Keycloak 认证

MinIO 支持多种配置 Keycloak 认证的方法

  • 使用 MinIO 租户控制台

  • 使用终端/Shell 和 mc idp openid 命令

您可以使用 MinIO 租户控制台将 Keycloak 配置为 MinIO 租户的外部身份提供程序。

使用 NodePort、Ingress 或负载均衡器端点访问控制台服务。您可以使用以下命令查看控制台配置

kubectl describe svc/TENANT_NAME-console -n TENANT_NAMESPACE

TENANT_NAMETENANT_NAMESPACE 分别替换为 MinIO 租户的名称及其命名空间。

以具有 MinIO 部署管理员权限的用户身份登录,例如具有 consoleAdmin 策略的用户。

从左侧导航栏中选择 身份,然后选择 OpenID。选择 创建配置 以创建新的配置。

在模态框中输入以下信息

名称

输入 Keycloak 实例的唯一名称

配置 URL

指定 Keycloak OpenID 配置文档的地址 (keycloak-service.keycloak-namespace.svc.cluster-domain.example)

确保 REALM 与您要用于对 MinIO 用户进行身份验证的 Keycloak realm 匹配。

客户端 ID

指定在步骤 1 中创建的 Keycloak 客户端的名称

客户端密钥

指定在步骤 1 中创建的 Keycloak 客户端的密钥凭据值

显示名称

指定 MinIO 控制台在为已配置的 Keycloak 服务的单点登录 (SSO) 工作流显示的用户界面名称

作用域

指定要包含在 JWT 中的 OpenID 作用域,例如 preferred_usernameemail

您可以使用支持的 OpenID 策略变量引用这些作用域,以便进行编程策略。

重定向 URI 动态

切换到

替换客户端使用的 MinIO 控制台地址作为 Keycloak 重定向 URI 的一部分。Keycloak 使用提供的 URI 将已认证的用户返回到控制台。

对于位于反向代理、负载均衡器或类似网络控制平面后面的 MinIO 控制台部署,您可以改为使用 MINIO_BROWSER_REDIRECT_URL 变量来设置 Keycloak 要使用的重定向地址。

选择 保存 以应用配置。

选择 保存 以应用配置。

您可以使用 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://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"

PRIMARY_IAM

设置为 Keycloak 服务的唯一标识符,例如 keycloak_primary

MINIO_CLIENT
MINIO_CLIENT_SECRET

设置为步骤 1 中配置的 Keycloak 客户端 ID 和密钥

config_url

设置为 Keycloak OpenID 配置文档的地址 (keycloak-service.keycloak-namespace.svc.cluster-domain.example)

display_name

设置为 MinIO 控制台在配置的 Keycloak 服务的单点登录 (SSO) 工作流程中显示的用户界面名称

scopes

设置为要包含在 JWT 中的 OpenID 范围列表,例如 preferred_usernameemail

redirect_uri_dynamic

设置为 on

替换客户端使用的 MinIO 控制台地址作为 Keycloak 重定向 URI 的一部分。Keycloak 使用提供的 URI 将已认证的用户返回到控制台。

对于位于反向代理、负载均衡器或类似网络控制平面后面的 MinIO 控制台部署,您可以改为使用 MINIO_BROWSER_REDIRECT_URL 变量来设置 Keycloak 要使用的重定向地址。

重新启动 MinIO 部署以应用更改。

检查 MinIO 日志并验证启动是否成功,且与 OIDC 配置相关的错误。

如果您尝试使用控制台登录,您现在应该会看到一个使用配置的 显示名称 的 (SSO) 按钮。

指定一个配置的用户并尝试登录。MinIO 应该会自动将您重定向到 Keycloak 登录入口。身份验证成功后,Keycloak 应该会将您重定向回 MinIO 控制台,使用原始控制台 URL 重定向 URI(如果已配置)。

5) 使用安全令牌服务 (STS) 生成应用程序凭证

使用与 S3 兼容的 SDK 的应用程序必须以访问密钥和密钥的形式指定凭证。MinIO AssumeRoleWithWebIdentity API 使用 Keycloak 身份验证后返回的 JWT 返回必要的临时凭证,包括所需的会话令牌。

您可以使用以下 HTTP 调用序列和 curl 实用程序来测试此工作流程

  1. 以 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"
    
    • USERPASSWORD 替换为 REALM 上的 Keycloak 用户的凭证。

    • CLIENTSECRET 替换为 REALM 上特定于 MinIO 的 Keycloak 客户端的客户端 ID 和密钥

    您可以使用 jq 或类似的 JSON 格式化实用程序处理结果。提取 access_token 字段以检索必要的访问令牌。注意 expires_in 字段以了解令牌过期前剩余的秒数。

  2. 使用 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 - 生成的凭证的过期日期

  3. 测试凭证

    使用您首选的与 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) 创建必要的客户端范围

导航到 客户端范围 视图并创建一个新的范围

名称

设置为范围的可识别名称 (minio-admin-API-access)

映射器

选择 配置新的映射器

受众

名称 设置为映射的可识别名称 (minio-admin-api-access-mapper)

包含的客户端受众

设置为 security-admin-console

导航到 客户端 并选择 MinIO 客户端

  1. 服务帐户角色 中,选择 分配角色 并分配 admin 角色

  2. 客户端范围 中,选择 添加客户端范围 并添加之前创建的范围

导航到 设置 并确保 身份验证流程 包括 服务 帐户 角色

2) 验证管理员 API 访问

您可以使用 MinIO 客户端凭证通过管理员 REST API 检索承载令牌和用户数据来验证功能

  1. 检索承载令牌

    curl -d "client_id=minio" \
         -d "client_secret=secretvalue" \
         -d "grant_type=password" \
         http://keycloak-url:port/admin/realms/REALM/protocol/openid-connect/token
    
  2. 使用返回值作为 access_token 访问管理员 API

    curl -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: falsenull(用户已从 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"