使用 Keycloak 身份提供商
Apache Polaris 入门:外部认证与 Keycloak
概述
本示例使用 Keycloak 作为 Polaris 的外部身份提供方。“iceberg” realm 由 iceberg-realm.json 文件自动创建并配置。
该 Keycloak realm 包含 1 个客户端定义:client1:s3cr3t。它被配置为返回具有以下固定声明(claims)的令牌:
principal_id:用户的主体 ID。在本示例中始终设置为零(0)。principal_name:用户的主体名称。在本示例中始终设置为“root”。principal_roles:用户的主体角色。在本示例中始终设置为["server_admin", "catalog_admin"]。
这显然不是一个真实的配置。在实际场景中,你会配置 Keycloak 以返回用户真实的主体 ID、名称和角色。请注意,主体和主体角色必须事先在 Polaris 中创建,并且其 ID、名称和角色必须与 Keycloak 返回的内容一致。
Polaris 配置了 3 个 realm:
realm-internal:这是默认 realm,配置为仅使用内部认证。它只接受 Polaris 自身签发的令牌。realm-external:该 realm 配置为仅使用外部身份提供方(IDP)进行认证。它只接受 Keycloak 签发的令牌。realm-mixed:该 realm 配置为同时使用内部和外部认证。它接受 Polaris 和 Keycloak 签发的令牌。
有关如何为 Polaris 配置外部认证的更多信息,请参阅 IDP 集成文档。
启动示例
如果本地尚未存在 Polaris 服务器镜像,先进行构建:
./gradlew \ :polaris-server:assemble \ :polaris-server:quarkusAppPartsBuild --rerun \ -Dquarkus.container-image.build=true在仓库根目录下运行以下命令来启动 docker compose 组:
docker compose -f getting-started/keycloak/docker-compose.yml up
请求令牌
注意:以下命令需要你的机器上已安装 jq。
从 Polaris 请求
你可以从 Polaris 为 realm-internal 和 realm-mixed 这两个 realm 请求令牌:
打开终端并运行以下命令,为
realm-internalrealm 请求访问令牌:polaris_token_realm_internal=$(curl -s http://localhost:8181/api/catalog/v1/oauth/tokens \ --user root:s3cr3t \ -H 'Polaris-Realm: realm-internal' \ -d 'grant_type=client_credentials' \ -d 'scope=PRINCIPAL_ROLE:ALL' | jq -r .access_token)
该令牌仅对 realm-internal realm 有效。
2. 打开终端,运行以下命令为 realm-mixed realm 请求访问令牌:
polaris_token_realm_mixed=$(curl -s http://localhost:8181/api/catalog/v1/oauth/tokens \
--user root:s3cr3t \
-H 'Polaris-Realm: realm-mixed' \
-d 'grant_type=client_credentials' \
-d 'scope=PRINCIPAL_ROLE:ALL' | jq -r .access_token)该令牌仅对 realm-mixed realm 有效。
Polaris 令牌的有效期为 1 小时。
注意:如果你为 realm-external realm 请求 Polaris 令牌,它将无法使用,因为 Polaris 不会为该 realm 签发令牌:
curl -v http://localhost:8181/api/catalog/v1/oauth/tokens \
--user root:s3cr3t \
-H 'Polaris-Realm: realm-external' \
-d 'grant_type=client_credentials' \
-d 'scope=PRINCIPAL_ROLE:ALL'由于该 realm 已停用内部令牌端点,因此会返回 501 Not Implemented 错误。
从 Keycloak 获取
你可以针对 realm-external 和 realm-mixed realm 向 Keycloak 请求令牌:
打开终端并运行以下命令,向 Keycloak 请求访问令牌:
keycloak_token=$(curl -s http://keycloak:8080/realms/iceberg/protocol/openid-connect/token \ --resolve keycloak:8080:127.0.0.1 \ --user client1:s3cr3t \ -d 'grant_type=client_credentials' | jq -r .access_token)
请注意 --resolve 选项:它用于发送请求,并将 Host 请求头设置为 keycloak。这是必需的,因为 Keycloak 签发的令牌其 iss 声明与请求的 Host 请求头一致;如果没有这个设置,令牌在用于访问 Polaris 时将无效,因为 iss 声明会是 127.0.0.1,而 Polaris 期望它是 keycloak,即 Keycloak 在 Docker 网络中的主机名。
Keycloak 签发的令牌可以用于通过 realm-external 或 realm-mixed realm 访问 Polaris。访问令牌的有效期为 1 小时。
你也可以访问 Keycloak 管理控制台。打开浏览器并访问 http://localhost:8080,然后使用用户名 admin 和密码 admin 登录(你可以在 docker-compose 文件中修改)。
使用令牌访问 Polaris
你可以使用上面获取的令牌来访问 Polaris。以下示例展示了如何在 curl 中使用这些令牌:
使用 Polaris 令牌
打开终端并运行以下命令,列出
realm-internalrealm 中的主体角色:curl -v http://localhost:8181/api/management/v1/catalogs \ -H "Authorization: Bearer $polaris_token_realm_internal" \ -H 'Polaris-Realm: realm-internal' \ -H 'Accept: application/json'打开终端并运行以下命令,列出
realm-mixedrealm 中的主体角色:curl -v http://localhost:8181/api/management/v1/catalogs \ -H "Authorization: Bearer $polaris_token_realm_mixed" \ -H 'Polaris-Realm: realm-mixed' \ -H 'Accept: application/json'
注意:不能混用来自不同 realm 的令牌。例如,不能使用 realm-internal realm 的令牌来访问 realm-mixed realm:
curl -v http://localhost:8181/api/management/v1/catalogs \
-H "Authorization: Bearer $polaris_token_realm_internal" \
-H 'Polaris-Realm: realm-mixed' \
-H 'Accept: application/json'这将返回 401 Unauthorized 错误,因为该令牌对 realm-mixed 领域无效。
使用 Keycloak 令牌
同一个 Keycloak 令牌可用于访问 realm-external 和 realm-mixed 两个领域,因为它对两者都有效(两个领域共享相同的 OIDC 租户配置)。
打开终端并运行以下命令,以列出
realm-external领域中的主体角色:curl -v http://localhost:8181/api/management/v1/catalogs \ -H "Authorization: Bearer $keycloak_token" \ -H 'Polaris-Realm: realm-external' \ -H 'Accept: application/json'打开终端并运行以下命令,以列出
realm-mixed领域中的主体角色:curl -v http://localhost:8181/api/management/v1/catalogs \ -H "Authorization: Bearer $keycloak_token" \ -H 'Polaris-Realm: realm-mixed' \ -H 'Accept: application/json'
注意:你无法使用 Keycloak 令牌来访问 realm-internal realm:
curl -v http://localhost:8181/api/management/v1/catalogs \
-H "Authorization: Bearer $keycloak_token" \
-H 'Polaris-Realm: realm-internal' \
-H 'Accept: application/json'这将返回 401 Unauthorized 错误,因为该令牌对 realm-internal realm 而言无效。
评论
登录后参与评论
KnowForge