使用 OIDC 和 ADFS 进行身份验证

本页面介绍如何将 OpenID Connect (OIDC) 与 Active Directory 联合身份验证服务 (ADFS) 结合起来使用,以配置 GKE On-Prem 用户集群的身份验证。

如需大致了解身份验证流程,请参阅身份验证

概览

GKE On-Prem 支持使用 OpenID Connect (OIDC) 作为与用户集群的 Kubernetes API 服务器进行交互的身份验证机制之一。为使集群用户能够自动完成身份验证流程,GKE On-Prem 提供了一个 kubectl 插件,即适用于 OIDC 的 Kubectl 插件。

在本练习中,您将使用一组 ADFS 管理向导来配置 kubectl 命令行工具、ADFS 服务器与 AD 员工数据库之间的关系。

准备工作

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

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

  • 企业为其员工数据库使用 Active Directory (AD)。
  • 企业运行 Active Directory 联合身份验证服务 (ADFS) 服务器。
  • ADFS 服务器充当 OpenID 提供方。

下载适用于 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 插件

创建重定向 URI

您必须提供可供 OpenID 提供方用来返回 ID 令牌的重定向 URI。令牌转到适用于 OIDC 的 Kubectl 插件,该插件会在每个员工的本地机器上运行并侦听您选定的端口。选择适合此用途且大于 1024 的端口号。因此,重定向 URI 为:

http://localhost:[PORT]/callback

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

配置 ADFS

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

设置重定向 URI

  1. 打开 ADFS 管理窗格。

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

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

  4. 输入您的重定向 URI。您将获得一个客户端 ID。这是 OpenID 提供商识别 kubectl 应用的方式。保存客户端 ID 以供日后使用。

  5. 选择 Generate a shared secretkubectl 应用使用此 Secret 通过 OpenID 提供方身份验证。保存此密钥以供日后使用。

配置安全群组(可选)

  1. 在 ADFS 管理中,选择 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. 对于访问控制政策,请选择允许所有人 (Permit everyone)。也就是说,所有员工都会与 kubectl oidc 共享他们的安全群组信息。

  8. 点击完成

将 LDAP 特性映射到声明名称

  1. 在 ADFS 管理中,选择 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,选择 Token Groups - Qualified Names。对于 Outgoing Claim Type,选择 groups

  6. 点击完成,然后点击应用

向 ADFS 注册 kubectl

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

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

其中:

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

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

在 GKE On-Prem 配置文件中填充 oidc 规范

在安装过程中,您可以使用 gkectl create-config 生成 GKE On-Prem 配置文件。配置包括以下 oidc 规范。使用特定于提供方的值来填充“oidc”:

oidc:
  issuerurl:
  kubectlredirecturl:
  clientid:
  clientsecret:
  username:
  usernameprefix:
  group:
  groupprefix:
  scopes:
  extraparams:
  usehttpproxy:
  capath:
  • issuerurl:您的 OpenID 提供方的网址,如 https://example.com/adfs。客户端应用(如适用于 OIDC 的 Kubectl 插件)向此网址发送授权请求。Kubernetes API 服务器使用此网址来发现用于验证令牌的公钥。必须使用 HTTPS。 此字段为必填字段。
  • kubectlredirecturl:适用于 OIDC 的 Kubectl 插件的 localhost 重定向网址。 您需要向 OpenID 提供方注册该重定向网址,以供分配给此集群的客户端 ID 使用。此字段是必填字段。
  • clientid:向 OpenID 提供方发出身份验证请求的客户端应用(如适用于 OIDC 的 Kubectl 插件)的 ID。此字段为必填字段。
  • clientsecret:客户端应用的密钥。 此字段为必填字段。
  • usehttpproxy:选择是否在集群中部署反向代理,以允许 Connect Agent 通过访问本地 OIDC 提供方来验证用户身份。值必须为字符串 "true""false"。此字段是必填字段。
  • username:用作用户名的 JWT 声明。默认值为 sub,这是最终用户的唯一标识符。您可以选择其他声明,如 emailname,具体取决于 OIDC 提供方。不过,email 以外的声明会以颁发者网址作为前缀,以防止命名与其他插件冲突。
  • usernameprefix:为防止与现有名称冲突而附加到用户名声明的前缀。如果未提供此标志,并且 username 是电子邮件地址以外的值,则前缀默认为 issueruri#。值 - 可用于停用所有前缀。
  • group:用作用户群组的 JWT 声明。如果存在声明,则它必须是字符串数组。
  • groupprefix:为防止与现有名称冲突而附加到群组声明的前缀。例如,假定群组名称为 foobar,前缀为 gid-,两者结合为 gid-foobar
  • scopes:以逗号分隔列表的形式发送到 OpenID 提供方的其他范围。
  • extraparams:要发送到 OpenID 提供方的其他键值参数。
  • capath:签署身份提供商的网络证书的证书授权机构 (CA) 的证书路径。

    GKE On-Prem 集群使用 TLS 来保护其组件之间的通信。要让 Kubernetes 在安装和节点引导期间自动生成客户端证书,必须使用 CA 安装 GKE On-Prem。

    默认情况下,GKE On-Prem 会在安装过程中创建一个新的 CA,以生成 TLS 证书。CA 和生成的证书存储在管理员集群本地。

示例:对群组进行身份验证和授权

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

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

因此,使用群组策略是最佳做法,因为 GID 既可以是永久性的,也更易于审核。

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

{
  '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-'
...

创建用户集群后,您接着可以使用 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

创建服务器证书授权机构 (CA) 证书

您的用户集群的 kubeconfig 将其主机的 CA 数据存储在其 certificate-authority-data 字段中。您需要解码该值并将解码后的值存储在诸如 server-ca-cert 这样的本地文件中:

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

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

针对 OpenID 设置集群并创建该集群后,用户可以通过将客户端身份验证配置文件传递给 kubectl oidc login 登录该集群。您可以通过输入以下命令生成客户端身份验证配置文件:

PowerShell

kubectl oidc client-config `
--issuer-uri [ISSUER_URI] `
--redirect-uri [REDIRECT_URI] `
--client-id [CLIENT_ID] `
--client-secret [CLIENT_SECRET] `
--scopes "allatclaims" `
--cluster-name [USER_CLUSTER_NAME] `
--server [CLUSTER_URL] `
--server-ca-file server-ca-cert `
--issuer-ca-file [ADFS_CA_CERT] `
--extra-params "resource=token-groups-claim"
> client-config.yaml
  • [ISSUER_URI] 是您的颁发者 URI。
  • [REDIRECT_URI] 是您的重定向 URI。
  • [CLIENT_ID] 是“kubectl”应用的客户端 ID。
  • [CLIENT_SECRET] 是为您生成的客户端密钥。
  • [USER_CLUSTER_NAME] 是您的用户集群的名称。
  • [CLUSTER_URL] 是集群的 Kubernetes API 服务器的网址。
  • --server-ca-file 接受您在上一部分创建的 CA 文件的路径。
  • [ADFS_CA_CERT] 是 ADFS CA 的公共证书文件的路径。
  • --extra-param 向 OIDC 提供方发送包含身份验证请求的键值对。

Linux

kubectl oidc client-config \
--issuer-uri [ISSUER_URI] \
--redirect-uri [REDIRECT_URI] \
--client-id [CLIENT_ID] \
--client-secret [CLIENT_SECRET] \
--scopes "allatclaims" \
--cluster-name [USER_CLUSTER_NAME] \
--server [CLUSTER_URL] \
--server-ca-file server-ca-cert \
--issuer-ca-file [ADFS_CA_CERT] \
--extra-params "resource=token-groups-claim"
> client-config.yaml
  • [ISSUER_URI] 是您的颁发者 URI。
  • [REDIRECT_URI] 是您的重定向 URI。
  • [CLIENT_ID] 是“kubectl”应用的客户端 ID。
  • [CLIENT_SECRET] 是为您生成的客户端密钥。
  • [USER_CLUSTER_NAME] 是您的用户集群的名称。
  • [CLUSTER_URL] 是集群的 Kubernetes API 服务器的网址。
  • --server-ca-file 接受您在上一部分创建的 CA 文件的路径。
  • [ADFS_CA_CERT] 是 ADFS CA 的公共证书文件的路径。
  • --extra-param 向 OIDC 提供方发送包含身份验证请求的键值对。

此命令会生成名为 client-config.yaml 的客户端身份验证文件。请勿手动修改此文件。 每个需要通过用户集群身份验证的员工都应拥有 client-config.yaml

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

如需使用客户端身份验证文件通过用户集群身份验证,请从本地机器或虚拟机执行以下步骤:

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

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

    其中:

    • [NAME] 是您选择的用户名。
    • [KUBECONFIG_OUTPUT_PATH] 是存储凭据的 kubeconfig 文件的输出位置。

    kubectl oidc login 会启动浏览器,供用户或员工输入其凭据。

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

  2. 您现在应该已通过身份验证。如需确定您是否已成功通过身份验证,请输入任意 kubectl 命令。例如:

    kubectl get nodes --kubeconfig [KUBECONFIG_OUTPUT_PATH]
    

总结

您的企业运行充当 OpenID 提供方的 ADFS 服务器。您的 OpenID 提供方了解 kubectl 应用,并了解 kubectl 可以请求 openidallatclaims 范围。

AD 数据库中的 Token-Groups Qualified Names LDAP 特性会映射到 OpenID 提供方中的 groups 声明。提供方会返回包含员工 ID、颁发者 ID、openid 声明和 groups 声明的令牌。groups 声明列出了员工所属的安全群组。

后续步骤