1. 介绍

概述

Keycloak 是一种用于现代应用程序和服务的开源身份和访问管理解决方案。开发人员通常要求编写的安全功能是开箱即用的,并且可以轻松根据组织的需求进行定制。Keycloak 提供了可定制的用户界面,用于登录、注册、帐户管理,支持单点登录(SSO)、用户注册和身份联合等用例。

Keycloak 还可以作为一个集成平台,将其连接到现有的 LDAP 和 Active Directory 服务器,并且可以将身份验证委托给第三方身份提供商,如 GitHub 和 Google。

Keycloak 的主要特点包括:

  1. 单点登录:支持 OpenID Connect、OAuth 2.0 和 SAML 2.0 等标准协议。
  2. 身份和访问管理:提供用户联合、强认证、用户管理和细粒度授权。可以将身份验证集成到应用程序和服务中,而无需处理用户存储或验证。

术语

下表列出了与此解决方案相关的关键术语:

术语 全名 说明
SSO 单点登录(Single-Sign On) 单点登录(SSO)是一种身份验证方案,允许用户使用单一的凭证登录多个相关但独立的软件系统。
SAML 安全断言标记语言(Security Assertion Markup Language) SAML 是一种开放标准,用于在各方之间交换身份验证和授权数据,特别是在身份提供者和服务提供者之间。它是一种基于 XML 的语言,用于进行安全断言。
OpenID OpenID OpenID 是由 OpenID 基金会推动的开放标准和去中心化的身份验证协议。有关详细信息,请参见 OpenID Connect。

在使用 Keycloak 来保护 Web 应用程序和 服务之前,了解以下核心概念和术语非常重要:

术语 说明
Realms Realms 是身份验证和授权的子域,用于管理和验证用户身份。每个 realm 都有自己的身份验证和授权配置。
Clients Clients 是使用 Keycloak 作为 API 客户端的程序或服务。Keycloak 提供了多个 API(例如 HTTP API、JSON API 和 WebSocket API)供客户端使用,客户端可以通过这些 API 访问 Keycloak 后端服务,获取访问令牌或其他授权资源。
Groups Groups 是一组具有相同权限的用户或客户端。用户可以加入多个 group,每个 group 都具有特定的权限范围。group 可以是基于用户的,也可以是基于客户端的。例如,可以创建一个名为“admin”的 group,将所有管理员添加到该 group 中,以便他们可以访问系统中的所有权限。
Users Users 是使用 Keycloak 的用户。Keycloak 提供多种验证用户身份的方式,例如密码、社会安全号码、护照等。用户可以在 Keycloak 中创建、修改或删除,并且可以通过 API 进行身份验证和授权。
Client Scopes Client Scopes 是授予客户端访问 Keycloak 后端服务的权限。Client scope 定义了一组权限,可以授予客户端,使其可以访问 Keycloak 后端服务。例如,可以创建一个名为“read”的 client scope,并将其授予可以读取特定资源的客户端。这样可以确保只有具有足够权限的客户端可以访问系统中的资源。

2. 安装与部署

准备工作

在开始部署 Keycloak 之前,请确保已完成以下准备工作:

  1. 拥有一个已经备案的域名。
  2. 获得对应域名的服务器管理权限,能够更新 DNS 解析记录。
  3. 在 AWS 控制台申请一台 t3a.medium 类型的 云主机(Linux 系统)。
  4. 申请并配置对应域名的 SSL 证书,并将证书放置在 EC2 主机的 /etc/ssl/ 目录下。

部署步骤

以 POC 环境为例,下面的步骤将指导您如何使用 EC2 初始化 K3S 集群,并在 K3S 集群中部署 Keycloak。

1. 初始化 K3S 集群

登录到 EC2 主机并下载以下部署脚本:

```bash wget https://github.com/svc-design/Modern-Container-Application-Reference-Architecture/blob/main/playbook/roles/k3s/files/setup-k3s-with-hostpath-sc.sh wget https://github.com/svc-design/Modern-Container-Application-Reference-Architecture/blob/main/playbook/roles/k3s/files/setup-ingress.sh wget https://github.com/svc-design/Modern-Container-Application-Reference-Architecture/blob/main/playbook/roles/keycloak/files/setup-keycloak.sh 按照以下顺序执行脚本:

bash 复制代码 bash setup-k3s-with-hostpath-sc.sh # 初始化 K3S 集群 bash setup-ingress.sh # 配置 K3S ingress 2. 创建 Keycloak Namespace 和 Secret 在 K3S 集群中创建 keycloak 命名空间,并生成 Secret:

bash 复制代码 kubectl create namespace keycloak # 创建 namespace kubectl create secret tls keycloak-tls –key=/etc/ssl/domain.key –cert=/etc/ssl/domain.cert -n keycloak # 创建 secret 3. 部署 Keycloak 执行以下命令来部署 Keycloak:

bash 复制代码 bash setup-keycloak.sh # 部署 Keycloak

其中,

  1. 配置 DNS 解析 部署完成后,获取域名和 IP 地址,并在 DNS 服务中添加解析记录。使用以下命令查看 Keycloak 的 ingress 记录:

bash 复制代码 kubectl get ingress -A | grep keycloak | awk ‘{print $4 “ $5}’ 这将返回类似以下格式的结果:

复制代码 keycloak.onwalk.net x.x.x.x 将上述域名和 IP 地址添加到您的 DNS 解析记录中,等待 DNS 解析生效。

  1. 访问 Keycloak 管理控制台 DNS 解析生效后,您可以在浏览器中访问 Keycloak 管理控制台,URL 示例: https://keycloak.onwalk.net 使用管理员用户名 user 和之前设置的 密码登录,将会看到 Keycloak 管理控制台的页面。

3. 配置

3.1 Keycloak 默认语言设置

登录到 Keycloak,点击左侧菜单栏中的 Realm Settings

  1. 点击 Themes,将所有属性设置为 keycloak
  2. Internationalization Enabled 选项中选择 ON
  3. Default Locale 设置为 zh-CN

重新登录时,在登录页面会显示语言切换项。

3.2 Keycloak 安全设置

选择需要配置的 Realm,点击左侧菜单中的 Authentication -> Required Actions,建议开启以下配置项:

3.3 Keycloak 新建 Realm

出于安全的需要,生产环境不建议直接使用默认的 Master,可以按照角色或不同用途建立不同的 Realm。

3.4 Keycloak 新建 Client

以新建 Gitlab OIDC 客户端为例,参考操作如下:

  1. Keycloak 侧配置:选择一个 Realm,左侧侧边栏点击 Clients,右侧点击 Create 客户端。

  2. 选择下一步,客户端验证:开启(关键配置项)。

    选择下一步:

  3. 保存并记录 gitlab-oidc 客户端密钥。

3.5 Keycloak 新建 User

在创建好的 Realm 中,创建属于这个 Realm 下的用户,Realm 之间具备逻辑隔离属性。

04. SSO 集成简介

单点登录(SSO)是一种认证方法,允许用户通过一次登录便可访问多个应用程序。在现代身份认证系统中,SAML 和 OIDC 是最常见的协议,它们分别适用于不同的场景。以下是这两种协议的概述。

SAML(Security Assertion Markup Language)

SAML 是一种基于 XML 的认证协议,主要用于企业级单点登录(SSO)解决方案。它允许用户在身份提供者(IdP)和服务提供者(SP)之间进行身份验证和授权交换。

适用场景:

SAML 的一个优势是它提供了强大的安全性,适用于需要处理复杂权限和安全策略的环境。然而,它的实现较为复杂,通常需要较长的配置和调试时间。

OIDC(OpenID Connect)

OIDC 是基于 OAuth 2.0 协议的身份认证协议,旨在简化现代 Web 应用程序和移动应用的身份认证过程。它允许客户端应用程序验证用户的身份,并获取有关用户的基本信息。

适用场景:

OIDC 的优势在于其简洁的实现和更高的扩展性,尤其适用于云原生应用和微服务架构。它与 SAML 相比,通常配置更加简单,适合快速集成和扩展。

根据具体应用场景选择合适的协议,可以更好地满足企业的身份认证需求和用户体验。

4.1 AWS SSO 配置

配置项目汇总

步骤 配置项目 Keycloak 控制台操作 AWS 控制台操作
1 创建 Realm 创建 Realm,命名为 cloud-sso
2 设置登录名为邮件 启用 Email as username 设置。
3 导出 SAML Metadata 导出 SAML 2.0 的 Metadata 文件(keycloak-saml-metadata.xml)。
4 添加身份提供商 IAM 中添加 SAML 2.0 身份提供商,导入 Keycloak SAML Metadata。
5 创建客户端 导入 AWS SAML Metadata,设置 IDP-Initiated SSO URL nameHome URL
6 创建 Realm 角色 创建 Realm 角色,格式为 <sso-iam-role-arn>,<identity-providers-arn>
7 更新客户端配置 配置 clientScopes,设置 Full scope allowedOff,并添加 assign role 操作。
8 配置 Session Role Mappers 中配置 Role list 映射器,设置 Role attribute namehttps://aws.amazon.com/SAML/Attributes/Role
9 配置 Session Name Mappers 中配置 User Property 映射器,设置 Role Attribute Namehttps://aws.amazon.com/SAML/Attributes/RoleSessionName
10 创建用户 在 Keycloak 中创建新用户,分配角色。
11 添加角色绑定 为身份提供商绑定角色并创建 IAM 角色。
12 配置角色权限 为 IAM 角色分配权限策略(如 AdministratorAccess)。
13 记录 ARN 记录 IAM 角色和身份提供商的 ARN。
14 导入 SAML Metadata 下载 AWS SAML Metadata 文件(AWS 中国和国际版)。
15 配置 Home URL 和 IDP-Initiated URL 设置 Home URLIDP-Initiated SSO URL
16 完成角色绑定 完成角色和权限的绑定,确保角色策略已正确分配给 SSO 用户。

4.1.1 Keycloak 控制台操作,创建 Realm

  1. 登录到 Keycloak 管理控制台,创建一个新的 Realm,命名为 cloud-sso
  2. 配置 Realm 域内的用户使用邮件作为默认登录名:

4.1.2 Keycloak 控制台操作,导出 Identity Provider Metadata

  1. 导出 Keycloak 的 SAML 2.0 Identity Provider Metadata 文件,并保存为 keycloak-saml-metadata.xml

4.1.3 AWS 控制台操作,添加身份提供商

  1. 登录 AWS 管理控制台,进入 IAM -> Identity Providers,点击 添加身份提供商
  2. 配置身份提供商,选择 SAML 协议:

4.1.4 AWS 控制台操作,为身份提供商绑定 IAM 角色

  1. 添加身份提供商后,点击 下一步 进入角色分配。
  2. 选择 创建新角色
  3. 选择受信任实体的类型为:SAML 2.0 身份联合
  4. SAML 提供商 处选择 keycloak-sso
  5. 允许 编程访问亚马逊云科技 管理控制台访问
  6. 点击 下一步,为角色设置权限,附加所需的权限策略(例如,AdministratorAccess)。
  7. 点击 下一步 设置标签,进行角色名称填写后,完成角色创建。示例角色名称为 sso-saml-admin
  8. 记录 IAM 角色 ARN 和身份提供商 ARN,这些信息将在后续的 Keycloak 客户端配置中使用。

注意:AWS 中国和 AWS 国际的配置略有差异: - AWS 中国账号 格式: - IAM角色 ARN:arn:aws-cn:iam::<aws-account-id>:role/sso-saml-admin - 身份提供商 ARN:arn:aws-cn:iam::<aws-account-id>:saml-provider/keycloak-sso - AWS 国际账号 格式: - IAM角色 ARN:arn:aws:iam::<aws-account-id>:role/sso-saml-admin - 身份提供商 ARN:arn:aws:iam::<aws-account-id>:saml-provider/keycloak-sso

4.1.5 Keycloak 控制台操作,创建客户端

  1. 下载 SAML Metadata 文件:
  2. 登录到 Keycloak 管理控制台,选择一个 Realm,点击左侧的 Clients,然后选择 导入客户端
  3. 选择下载的 Metadata 文件进行导入,点击 Save 保存配置。
  4. 修改以下配置:

4.1.6 Keycloak 控制台操作,创建 Realm 角色

  1. Realm Roles 选项卡下,创建新的角色用于授权 Keycloak 用户,格式如下:

4.1.7 Keycloak 控制台操作,更新客户端配置

  1. 进入 Client -> urn:amazon:webservices:cn-north-1,选择 clientScopes,点击 urn:amazon:webservices:cn-north-1
  2. scope 设置中,选择 Full scope allowedOff
  3. 删除 Role List,执行 assign role 操作,将步骤 4.1.6 中创建的 Realm 角色分配给客户端。

4.1.8 Keycloak 控制台操作,调整 Session Role 配置

  1. 更新客户端配置:进入 Client -> urn:amazon:webservices:cn-north-1,选择 clientScopes -> urn:amazon:webservices:cn-north-1-dedicated -> Mappers
  2. 删除原有的 Role 配置,重新添加以下配置:

4.1.9 Keycloak 控制台操作,调整 Session Name 配置

  1. 更新客户端配置:进入 Client -> urn:amazon:webservices:cn-north-1,选择 clientScopes -> urn:amazon:webservices:cn-north-1-dedicated -> Mappers
  2. 删除原有的 Role Session 配置,重新添加以下配置:

4.1.10 Keycloak 控制台操作,新增用户

  1. 在 Keycloak 控制台中,创建新用户。
  2. 清除原有的 role 配置,并执行 Assign role 操作,将步骤 4.1.6 中创建的 Realm 角色分配给该用户。

4.1.11 Keycloak 控制台操作,验证 SSO 登录

  1. 使用浏览器访问 Home URL,例如:https://keycloak.onwalk.net/realms/cloud-sso/protocol/saml/clients/aws-cn-sso

5.7 Gitlab OIDC SSO 配置

5.7.1 Keycloak控制台操作:新建Gitlab OIDC客户端

  1. Keycloak侧配置:
  2. 选择下一步:
  3. 选择下一步:
  4. 保存,并记录生成的 gitlab-oidc 客户端密钥。

5.7.2 Gitlab侧配置:开启OIDC登录选项

Helm 部署 Gitlab 为例,进行如下配置:

  1. 创建存储OIDC认证信息的 Secret: ```bash cat > provider.yaml << EOF name: ‘openid_connect’ label: ‘keycloak-sso’ args: name: ‘openid_connect’ scope: - ‘openid’ - ‘profile’ - ‘email’ pkce: true discovery: true response_type: ‘code’ client_auth_method: ‘query’ send_scope_to_token_endpoint: true issuer: ‘https://keycloak.apollo-ev.com/realms/cloud-sso’ client_options: identifier: ‘gitlab-oidc’ secret: ‘gitlab-oidc-token’ redirect_uri: ‘https://gitlab.apollo-ev.com/users/auth/openid_connect/callback’ EOF

    export KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl delete secret gitlab-sso-secret -n gitlab || echo true kubectl create secret generic gitlab-sso-secret –from-file=“provider=provider.yaml” -n gitlab

更新 Gitlab 部署配置: 修改 gitlab-values.yaml,添加以下配置:

yaml 复制代码 global: appConfig: omniauth: enabled: true autoLinkLdapUser: false autoLinkSamlUser: false blockAutoCreatedUsers: false autoSignInWithProvider: null autoLinkUser: - ‘openid_connect’ allowSingleSignOn: - ‘openid_connect’ providers: - secret: gitlab-sso-secret key: provider 更新 Gitlab 部署:

bash 复制代码 helm repo add gitlab https://charts.gitlab.io/ helm repo up helm upgrade –install gitlab gitlab/gitlab –namespace gitlab -f gitlab-values.yaml

Gitlab 更新后,重新打开 Gitlab 登录页面,您将看到新的 sign in with keycloak-sso 选项。

5.8 Harbor OIDC SSO 配置

5.8.1 Keycloak控制台操作:新建 Harbor OIDC 客户端

  1. Keycloak 侧配置:
  2. 选择下一步:
  3. 选择下一步:
  4. 保存,并记录生成的 harbor-oidc 客户端密钥。

5.8.2 Harbor侧配置:开启 OIDC 登录选项

  1. 如果 Harbor 已经配置过本地数据库用户:
  2. 登录 Harbor 控制台,添加 OIDC 认证模式配置:
  3. 重新打开 Harbor 登录页面:

5.9 Grafana OIDC SSO 配置

5.9.1 Keycloak控制台操作:新建 Grafana OIDC 客户端

  1. Keycloak 侧配置:
  2. 选择下一步:
  3. 选择下一步:
  4. 保存,并记录生成的 grafana-oidc 客户端密钥。

5.9.2 Grafana侧配置:开启 OIDC 登录选项

  1. 修改 grafana.ini 配置:

  2. 添加以下配置: ```ini [server] domain = root_url = %(protocol)s://%(domain)s:%(http_port)s/ serve_from_sub_path = true

    [auth.generic_oauth] enabled = true name = oidc-sso allow_sign_up = true auto_login = false client_id = grafana-oidc client_secret = scopes = openid email profile roles email_attribute_path = email login_attribute_path = username name_attribute_path = full_name auth_url = https:///realms/cloud-sso/protocol/openid-connect/auth token_url = https:///realms/cloud-sso/protocol/openid-connect/token api_url = https://realms/cloud-sso/protocol/openid-connect/userinfo role_attribute_path = contains(roles[*], ‘admin’) && ‘Admin’ || contains(roles[*], ‘editor’) && ‘Editor’ || ‘Viewer’ 更新 ConfigMap 后,重启 Grafana Pod:

重启 Grafana 服务以使配置生效。 bash 复制代码 kubectl rollout restart deployment grafana -n monitoring 重新打开 Grafana 登录页面:

登录页面将会新增 Sign in with oidc-sso 选项。 这样,你就成功为 Grafana 配置了基于 Keycloak 的 OIDC SSO 登录。

这段内容已整理为 5.9 Grafana OIDC SSO 配置,包括了在 Keycloak 和 Grafana 侧进行的所有配置

References

  1. https://www.keycloak.org/documentation
  2. https://aws-samples.github.io/keycloak-on-aws/en/
  3. https://docs.gitlab.com/ee/administration/auth/oidc.html
  4. https://git.xcvtc.edu.cn/help/administration/auth/oidc.md
  5. https://grafana.com/tutorials/run-grafana-behind-a-proxy/
  6. https://community.grafana.com/t/grafana-generic-oauth-with-keycloak/9692
  7. https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/keycloak/