使用 OIDC 和 AD FS 进行身份验证

本页面介绍如何将 OpenID Connect (OIDC) 与 Active Directory Federation Services (AD FS) 搭配使用,为 GKE On-Prem 用户集群配置身份验证。

如需简要了解身份验证流程,请参阅身份验证。如需了解如何使用 AD FS 以外的 OpenID 提供商,请参阅使用 OpenID Connect 进行身份验证

概览

GKE On-Prem 支持使用 OpenID Connect (OIDC) 作为与用户集群的 Kubernetes API 服务器进行交互的身份验证机制之一。借助 OIDC,您可以按照组织中创建、启用和停用员工帐号的标准过程来管理对 Kubernetes 集群的访问权限。

员工可以通过两种方式使用 OIDC 身份验证流程:

  • 员工可以使用 kubectl 启动 OIDC 流程。为了实现此流程的自动化,GKE On-Prem 提供适用于 OIDC 的 Kubectl 插件,这是一个 kubectl 插件

  • 员工可以使用 Google Cloud Console 启动 OIDC 身份验证流程。

在本练习中,您将配置两个选项:kubectl 和 Google Cloud 控制台。您可以使用一组 AD FS 管理向导来配置 AD FS 服务器和 AD 员工数据库。

准备工作

本主题假定您熟悉 OAuth 2.0OpenID Connect。本主题假定您熟悉 OpenID 范围声明

本主题适用于具有以下基础架构的企业:

  • 企业为其员工数据库使用 Active Directory (AD)。
  • 企业运行 Active Directory Federation Services (AD FS) 服务器。
  • AD FS 服务器充当 OpenID 提供商。

下载适用于 OIDC 的 Kubectl 插件

本部分面向希望使用适用于 OIDC 的 Kubectl 插件的管理员和员工。

下载插件并设置访问权限:

Linux

gsutil cp gs://gke-on-prem-release/oidc-plugin/v1.1alpha/linux_amd64/kubectl-oidc .
chmod +x kubectl-oidc

Windows

gsutil cp gs://gke-on-prem-release/oidc-plugin/v1.1alpha/windows_amd64/kubectl-oidc .

macOS

gsutil cp gs://gke-on-prem-release/oidc-plugin/v1.1alpha/darwin_amd64/kubectl-oidc .
chmod +x kubectl-oidc

安装插件

通过将可执行文件移到 PATH 上的任意位置来安装插件。可执行文件必须命名为 kubectl-oidc。如需了解详情,请参阅安装 kubectl 插件

为适用于 OIDC 的 Kubectl 插件创建重定向网址

本部分面向管理员。

作为与 AD FS 服务器建立关系的一部分,您必须指定一个重定向网址,以便 AD FS 服务器使用此网址将 ID 令牌返回到适用于 OIDC 的 Kubectl 插件。适用于 OIDC 的 Kubectl 插件在每位员工的本地机器上运行,并侦听您选择的端口。选择适合此用途且大于 1024 的端口号。然后,重定向网址为:

http://localhost:[PORT]/callback

其中,[PORT] 是您的端口号。

配置 AD FS 服务器时,请指定 http://localhost:[PORT]/callback 作为您的重定向网址之一。

为 Google Cloud 控制台配置重定向网址

本部分面向管理员。

除了拥有适用于 OIDC 的 Kubectl 插件的重定向网址之外,您还需要一个 Google Cloud 控制台重定向网址。Google Cloud 控制台的重定向网址为:

https://console.cloud.google.com/kubernetes/oidc

配置 AD FS 服务器时,请指定 https://console.cloud.google.com/kubernetes/oidc 作为您的重定向网址之一。

配置 AD FS

以下部分介绍如何为 GKE On-Prem 配置 AD FS。

设置重定向网址

  1. 打开 AD FS 管理窗格。

  2. 选择 Application Groups > Actions > Add an Application Group

  3. 选择 Server Application。输入您选择的名称和说明。点击 Next

  4. 输入您的两个重定向网址。您将获得一个客户端 ID。这是 AD FS 服务器标识适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台的方式。保存客户端 ID 以供日后使用。

  5. 选择 Generate a shared secret。适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台均使用此 Secret 向 AD FS 服务器进行身份验证。保存此 Secret 以供日后使用。

配置安全群组(可选)

  1. 在 AD FS 管理中,选择 Relying party trusts > Add a new relying party trust

  2. 选择 Claims aware,然后点击 Start

  3. 选择 Enter data about relying party manually

  4. 输入显示名。

  5. 跳过接下来的两个步骤。

  6. 输入信赖方信任标识符。建议使用 token-groups-claim

  7. 对于 Access control policy,请选择 Permit everyone。这意味着所有员工都会与适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台共享其安全群组信息。

  8. 点击完成

将 LDAP 特性 (Attribute) 映射到声明名称

  1. 在 AD FS 管理中,选择 Relying party trusts > Edit claim issuance policy

  2. 选择 Send LDAP Attributes as Claims,然后点击 Next

  3. 对于 Claim rule name,请输入 groups

  4. 对于 Attribute store,请选择 Active Directory

  5. 在表格中,对于 LDAP Attribute,请选择:

    • AD FS 5.0 及更高版本:Token-Groups Qualified by Domain name
    • AD FS 5.0 之前的版本:Token Groups - Qualified Names
  6. 对于 Outgoing Claim Type,请选择:

    • AD FS 5.0 及更高版本:Group
    • AD FS 5.0 之前的版本:groups
  7. 点击 Finish,然后点击 Apply

向 AD FS 注册适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台

在管理员模式下打开 PowerShell 窗口,然后输入以下命令:

Grant-AD FSApplicationPermission `
    -ClientRoleIdentifier "[CLIENT_ID]" `
    -ServerRoleIdentifier [SERVER_ROLE_IDENTIFIER] `
    -ScopeName "allatclaims", "openid"

其中:

  • [CLIENT_ID] 是您之前获得的客户端 ID。

  • [SERVER_ROLE_IDENTIFIER] 是您之前输入的声明标识符。回想一下,建议的标识符为 token-groups-claim

在集群配置文件中填充 oidc 规范

本部分面向希望创建配置为使用 OIDC 的集群的员工。

在创建用户集群之前,可使用 gkectl create-config 生成 GKE On-Prem 配置文件。配置包括以下 oidc 规范。使用提供方特定的值来填充 oidc

oidc:
  issuerurl:
  clientid:
  clientsecret:
  username:
  usernameprefix:
  group:
  groupprefix:
  scopes:
  extraparams:
  usehttpproxy:
  capath:
  • issuerurl:必填。您的 OpenID 提供商的网址,例如 https://example.com/adfs。客户端应用(如适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台)会向此网址发送授权请求。Kubernetes API 服务器使用此网址来发现用于验证令牌的公钥。必须使用 HTTPS。
  • clientid:必填。向 OpenID 提供商发出身份验证请求的客户端应用的 ID。适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台都使用此 ID。
  • clientsecret:可选。客户端应用的密钥。适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台均使用此密钥。
  • username:可选。用作用户名的 JWT 声明。默认值为 sub,该值应为最终用户的唯一标识符。您可以选择其他声明,例如 emailname,具体取决于 OpenID 提供方。不过,email 以外的声明会以颁发者网址作为前缀,以防止命名与其他插件冲突。
  • usernameprefix:可选。附加到用户名声明前面的前缀,以防止与现有名称冲突。如果您未提供此字段,并且 usernameemail 以外的值,则前缀默认为 issuerurl#。您可以使用值 - 停用所有前缀。
  • group:可选。提供方将用于返回安全群组的 JWT 声明。
  • groupprefix:可选。附加到群组声明前面的前缀,以防止与现有名称冲突。例如,给定一个组 foobar 和一个前缀 gid-,则格式为 gid-foobar
  • scopes:可选。以英文逗号分隔列表的形式发送给 OpenID 提供方的额外范围。
  • extraparams:可选。以英文逗号分隔列表的形式发送到 OpenID 提供方的额外键值对参数。
  • usehttpproxy:可选。指定是否在集群中部署反向代理,以允许 Connect Agent 访问本地 OIDC 提供方来验证用户身份。值必须是字符串:"true""false"
  • capath:可选。证书授权机构 (CA)(负责颁发身份提供方 Web 证书)颁发的证书路径。此值可能不是必需的。例如,如果您的身份提供方证书是由知名公共 CA 颁发的,那么您无需在此提供值。

示例:向用户和群组授权

许多提供方在令牌中对用户标识属性(例如电子邮件和用户 ID)进行编码。但是,对于身份验证政策来说,这些属性具有潜在的风险:

  • 用户 ID 可能会导致政策难以阅读和审核。
  • 电子邮件可能会产生可用性风险(如果用户更改其主电子邮件),也可能产生安全风险(如果可以重新分配电子邮件)。

因此,最佳做法是使用群组政策,因为群组 ID 是永久性 ID 且更易于审核。

假设您的提供方创建了包含以下字段的身份令牌:

{
  'iss': 'https://server.example.com'
  'sub': 'u98523-4509823'
  'groupList: ['developers@example.corp', 'us-east1-cluster-admins@example.corp']
  ...
}
根据此令牌格式,您可以按如下方式填充配置文件的 oidc 规范:
issueruri: 'https://server.example.com'
username: 'sub'
usernameprefix: 'uid-'
group: 'groupList'
groupprefix: 'gid-'
extraparams: 'resource=token-groups-claim'
...

创建用户集群后,您可以使用 Kubernetes 基于角色的访问权限控制 (RBAC) 向经过身份验证的用户授予具有特权的访问权限。例如,您可以创建一个 ClusterRole,向其用户授予对集群 Secret 的只读权限,并创建一个 ClusterRoleBinding 资源,以将角色绑定到经过身份验证的群组:

ClusterRole

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  # The resource type for which access is granted
  resources: ["secrets"]
  # The permissions granted by the ClusterRole
  verbs: ["get", "watch", "list"]

ClusterRoleBinding

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-secrets-admins
subjects:
  # Allows anyone in the "us-east1-cluster-admins" group to
  # read Secrets in any namespace within this cluster.
- kind: Group
  name: gid-us-east1-cluster-admins # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
  # Allows this specific user to read Secrets in any
  # namespace within this cluster
- kind: User
  name: uid-u98523-4509823
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

保存 Kubernetes API 服务器的 CA 证书

本部分面向已创建用户集群并且现在想要使用适用于 OIDC 的 Kubectl 插件的员工。

您的用户集群具有 Kubernetes API 服务器。您的用户集群的 kubeconfig 文件存储将证书颁发给 Kubernetes API 服务器的 CA 的证书。CA 的证书是 certificate-authority-data 字段的 base-64 编码值。您需要解码此值并将其存储在本地文件(例如 server-ca-cert)中:

cat [USER_CLUSTER_KUBECONFIG]  | grep certificate-authority-data | awk '{ print $2}' | base64 --decode > server-ca-cert

生成客户端身份验证配置文件

本部分面向已创建用户集群并且现在想要使用适用于 OIDC 的 Kubectl 插件的员工。

如需生成客户端身份验证配置文件,请输入以下命令:

Linux

kubectl oidc client-config \
--issuer-uri [ISSUER_URI] \
--redirect-uri [REDIRECT_URL] \
--client-id [CLIENT_ID] \
--client-secret [CLIENT_SECRET] \
--scopes "[CUSTOM_SCOPES]" \
--cluster-name [USER_CLUSTER_NAME] \
--server [CLUSTER_URL] \
--server-ca-file [SERVER_CA_CERT] \
--issuer-ca-file [PROVIDER_CA_CERT] \
--extra-params [KEY]=[VALUE], ... # e.g. --extra-params "resource=token-groups-claim"
> client-config.yaml

其中:

  • [ISSUER_URI] 是您的颁发者 URI。
  • [REDIRECT_URL] 是适用于 OIDC 的 Kubectl 插件的重定向网址
  • [CLIENT_ID] 是适用于 OIDC 的 Kubectl 插件的客户端 ID。
  • [CLIENT_SECRET] 是适用于 OIDC 的 Kubectl 插件的客户端密钥。
  • [USER_CLUSTER_NAME] 是您的用户集群的名称。
  • [CLUSTER_URL] 是用户集群的 Kubernetes API 服务器的网址。
  • [SERVER_CA_FILE] 是向 Kubernetes API 服务器颁发证书的 CA 的证书路径。这是您在上一部分中创建的证书文件。
  • [PROVIDER_CA_CERT] 是对 OpenID 提供方的证书进行签名的 CA 的证书路径。这与集群配置文件中 oidc:cacert 的值相同。
  • [CUSTOM_SCOPES] 是以英文逗号分隔的安全组的自定义范围列表。这与集群配置文件中 oidc:scopes 的值相同。
  • --extra-params [KEY]=[VALUE], ... 是要包含在向 OpenID 提供方发出的授权请求中的以英文逗号分隔的键值对列表。

PowerShell

kubectl oidc client-config `
--issuer-uri [ISSUER_URI] `
--redirect-uri [REDIRECT_URL] `
--client-id [CLIENT_ID] `
--client-secret [CLIENT_SECRET] `
--scopes "[CUSTOM_SCOPES]" `
--cluster-name [USER_CLUSTER_NAME] `
--server [CLUSTER_URL] `
--server-ca-file [SERVER_CA_CERT] `
--issuer-ca-file [PROVIDER_CA_CERT] `
--extra-params [KEY]=[VALUE]
> client-config.yaml

其中:

  • [ISSUER_URI] 是您的颁发者 URI。
  • [REDIRECT_URL] 是适用于 OIDC 的 Kubectl 插件的重定向网址
  • [CLIENT_ID] 是适用于 OIDC 的 Kubectl 插件的客户端 ID。
  • [CLIENT_SECRET] 是适用于 OIDC 的 Kubectl 插件的客户端密钥。
  • [USER_CLUSTER_NAME] 是您的用户集群的名称。
  • [CLUSTER_URL] 是用户集群的 Kubernetes API 服务器的网址。
  • [SERVER_CA_FILE] 是向 Kubernetes API 服务器颁发证书的 CA 的证书路径。这是您在上一部分中创建的证书文件。
  • [PROVIDER_CA_CERT] 是对 OpenID 提供方的证书进行签名的 CA 的证书路径。这与集群配置文件中 oidc:cacert 的值相同。
  • [CUSTOM_SCOPES] 是以英文逗号分隔的安全组的自定义范围列表。这与集群配置文件中 oidc:scopes 的值相同。
  • --extra-params [KEY]=[VALUE], ... 是要包含在向 OpenID 提供方发出的授权请求中的以英文逗号分隔的键值对列表。

此命令会生成名为 client-config.yaml 的客户端身份验证配置文件。请勿手动修改此文件。

使用适用于 OIDC 的 Kubectl 插件向用户集群进行身份验证

本部分面向已创建用户集群并且现在想要使用适用于 OIDC 的 Kubectl 插件的员工。

  1. 使用 client-config.yaml 文件初始化插件:

    kubectl oidc login --clientconfig-file=client-config.yaml --user [NAME] \
        --kubeconfig [KUBECONFIG_OUTPUT_PATH]

    其中:

    • [NAME] 是您的用户名。
    • [KUBECONFIG_OUTPUT_PATH] 是适用于 OIDC 的 Kubectl 插件将在其中存储凭据的 kubeconfig 文件的路径。

    kubectl oidc login 会启动浏览器,您可以在其中输入凭据。

    现在提供的 kubeconfig 文件包含一个 ID 令牌,kubectl 可使用该令牌向用户集群上的 Kubernetes API 服务器进行身份验证。

    注意:Windows 用户可能必须以 kubectl-oidc.exe login(而非 kubectl oidc login)的形式运行该命令。

  2. 通过运行任何 kubectl 命令来验证身份验证是否成功。例如:

    kubectl get nodes --kubeconfig [KUBECONFIG_OUTPUT_PATH]

将 OIDC 与 Google Cloud Console 搭配使用

本部分面向已创建用户集群并且现在想要使用 Google Cloud Console 向该集群进行身份验证的员工。

  1. 验证您的集群是否已针对 OIDC 进行了配置

  2. 验证您的集群是否已向 Google Cloud 注册(无论是在创建集群过程中自动注册还是手动注册)。

  3. 访问 Google Cloud 控制台中的 Kubernetes 集群页面。

    访问 Kubernetes 集群页面

  4. 在集群列表中,找到您的 GKE On-Prem 集群,然后点击登录

  5. 选择使用为集群配置的身份提供商服务执行身份验证,然后点击登录

    系统会将您重定向到您的身份提供商,您可能需要登录或同意 Google Cloud 控制台访问您的帐号。然后,系统会将您重定向回 Google Cloud 控制台中的 Kubernetes 集群页面。

总结

您的企业运行充当 OpenID 提供商的 AD FS 服务器。您的 OpenID 提供商知晓您的两个客户端应用:适用于 OIDC 的 Kubectl 插件和 Google Cloud 控制台。您的 OpenID 提供商知晓您的客户端应用可以请求 openidallatclaims 范围。

在 AD FS 5.0 之前的版本中,AD 数据库中的 Token-Groups Qualified Names LDAP 特性被映射到 OpenID 提供商中的 groups 声明。在 5.0 和更高版本中,该特性为 Token-Groups Qualified by Domain name。提供商会返回包含员工 ID、颁发者 ID、openid 声明和 groups 声明的令牌。groups(在 5.0 中为 Group)声明会列出员工所属的安全群组。

排查 GKE On-Prem 中的 OIDC 问题

配置无效

如果 Google Cloud 控制台无法从集群中读取 OIDC 配置,则登录按钮将被停用。

提供商配置无效

如果您的身份提供方配置无效,点击登录后,身份提供方将显示错误屏幕。按照特定于提供方的说明正确配置提供方或您的集群。

权限无效

如果您完成了身份验证流程,但仍看不到集群的详细信息,请确保您已向与 OIDC 搭配使用的帐号授予了正确的 RBAC 权限。请注意,此帐号可能与您用于访问 Google Cloud 控制台的帐号不同。

Error: missing 'RefreshToken' field in 'OAuth2Token' in credentials struct

如果授权服务器提示是否同意,但您未提供所需的身份验证参数,则可能会遇到此错误。向 GKE On-Prem 配置文件的 oidc: extraparams 字段提供 prompt=consent 参数,并使用 --extra-params prompt=consent 标志重新生成客户端身份验证文件。

后续步骤