Keycloak Client 的认证流程怎么选?从用户登录到服务调用

创建 Keycloak Client 时,你可能会看到 Standard Flow、Direct Access Grants、Service accounts roles 等选项。它们的名字相似,却对应不同的使用场景:有的是让用户登录,有的是让后台服务以自己的身份调用 API。

理解这些选项,先问两个问题:这次访问代表用户,还是代表应用自己?如果代表用户,用户在哪里完成登录?

本文以 OpenID Connect(OIDC)Client 为例。不同 Keycloak 版本的界面和选项位置可能不同。文中的地址、角色和请求都是演示示例,不是实测记录。

先看图中左侧的用户登录和右侧的服务调用:两条路径代表不同的身份。左侧还列出了普通浏览器登录和输入受限设备的两种选择。

先区分 Client、用户和令牌

假设你正在开发一个内部工单系统。员工是用户;在 Keycloak 中注册的工单系统是 Client;Keycloak 负责认证并按配置签发令牌。

Client 可以是网站、手机应用,也可以是后台服务。不同令牌也有不同用途:Access Token 用于访问受保护的资源;ID Token 向应用提供用户身份信息;Refresh Token 在符合配置条件时用于获取新的令牌。不要假设每种流程都会返回所有类型的令牌。

OAuth 2.0 主要定义授权机制。OIDC 建立在 OAuth 2.0 之上,为应用提供用户身份认证能力。Keycloak 的这些开关允许 Client 使用不同的协议流程。

Standard Flow:大多数用户登录的起点

Standard Flow 对应 Authorization Code Flow,授权码流程。它适合有用户参与的 Web 应用、单页应用(SPA)和手机应用。

以工单系统为例,用户访问应用时,应用让浏览器跳转到 Keycloak。用户完成认证后,Keycloak 把浏览器送回应用配置的回调地址,并附带一个短期有效的授权码。应用随后向 Keycloak 的 Token Endpoint 提交授权码,换取令牌。

用户通常在 Keycloak 或受信任的身份提供商页面完成认证。具体使用密码、一次性验证码还是其他方式,取决于 Keycloak 的认证配置。应用不需要直接收集用户密码。

为什么还需要 PKCE?

PKCE 为授权码兑换增加校验。应用先生成随机的 code_verifier,再根据它生成 code_challenge,在发起登录时发送 challenge。兑换授权码时,应用提交原始 verifier;Keycloak 检查两者是否匹配。

如果授权码被截获,攻击者通常还需要正确的 verifier 才能兑换令牌。SPA 和手机应用应使用 PKCE 的 S256 方法;服务端应用也建议使用。Keycloak 可以配置要求 S256,应用或 OIDC 库也必须发送相应参数。

配置回调地址时,使用应用实际需要的 Valid Redirect URIs ,避免不必要的宽泛匹配。应用还应使用成熟的 OIDC 库处理 state、nonce、令牌验证等细节。

Direct Access Grants:应用直接处理用户密码

Direct Access Grants 对应 OAuth 2.0 的 Resource Owner Password Credentials Grant,也叫密码授权。用户把用户名和密码交给应用,应用再将凭证发送给 Keycloak,请求用户令牌。

这个流程让应用直接接触用户密码,也限制了身份提供商登录、用户注册和其他需要交互的认证步骤。当前 OAuth 2.0 安全最佳实践明确规定不得使用该授权类型。新系统应使用授权码流程等替代方案;维护旧系统时,应将它作为需要迁移的兼容问题处理。

Implicit Flow:早期浏览器应用使用的流程

Implicit Flow 是较早的浏览器授权流程。Keycloak 通过浏览器重定向响应直接返回令牌,而不是先返回授权码,再让应用兑换令牌。

令牌经过浏览器重定向过程会带来额外的泄露风险;该流程也不提供 Refresh Token。Keycloak 不建议使用它。对新建 SPA,通常应选择 Standard Flow + PKCE。

Service accounts roles:后台服务代表自己访问

Service accounts roles 启用的是 Client Credentials Grant,客户端凭证授权。这里没有具体用户登录:Client 使用自己的凭证向 Keycloak 请求令牌,并以服务账号的身份访问 API。

例如,一个夜间任务需要调用报表 API。可以为任务创建独立 Client,开启 Client authentication 和 Service accounts roles,再为它的 Service Account 分配所需角色。Client 凭证可以是 Secret,也可以使用 Keycloak 支持的其他认证方式。

需要注意,分配给 Service Account 的角色不一定全部进入令牌。Keycloak 还会考虑 Client 及其关联 Client Scopes 的 role scope mappings;实际 claim 也受 protocol mapper 配置影响。目标 API 则需要验证令牌的签名、有效期、签发方、受众和权限。

下面是令牌请求的结构示例,未在真实环境执行:

bash 复制代码
curl --request POST \
  'https://sso.example.com/realms/company/protocol/openid-connect/token' \
  --user 'report-job:CLIENT_SECRET' \
  --data-urlencode 'grant_type=client_credentials'

CLIENT_SECRET 是占位符。实际使用时,应通过秘密管理机制提供凭证,避免把真实 Secret 写进代码或提交到 Git。注意命令行参数也可能被其他本机用户查看。

如果后台服务需要代表某个用户操作,Client Credentials 本身并不能表达这个用户身份,需要另行设计用户令牌的传递或委派。

Device Authorization Grant:在另一台设备上登录

这个流程适合没有合适浏览器,或输入不方便的设备,例如智能电视和部分命令行工具。

设备先向 Keycloak 请求设备授权,然后向用户显示验证地址和用户码。用户在手机或电脑上打开该地址,输入代码并完成登录。设备定期查询授权结果,完成后获取令牌。

这里仍然是用户授权;不同之处在于,用户在另一台设备上完成登录。使用时也要引导用户检查设备和请求,避免误批准陌生请求。

OIDC CIBA Grant:从后台发起用户认证

CIBA 的全称是 Client-Initiated Backchannel Authentication。Client 通过后台向 Keycloak 发起认证请求;用户通过另一个认证渠道完成认证,Client 再获取认证结果。

例如,某些系统需要用户在独立的认证设备上确认操作。但启用 CIBA 开关并不等于自动获得完整的手机推送系统。Keycloak 的 CIBA 还涉及认证渠道等配置和组件。只有系统确有这种需求时,才需要评估这项能力。普通网站登录通常从 Standard Flow 开始。

Client authentication 与流程选择是两回事

Client authentication 回答的是:Keycloak 是否需要验证 Client 自身的身份? 它与选择哪种用户登录流程是两个不同的配置问题。

能够安全管理凭证的服务端应用,通常开启 Client authentication,作为 confidential client。运行在用户浏览器或手机上的应用无法可靠地保守共享 Secret,通常关闭它,作为 public client,并使用授权码流程和 PKCE。

Service Account 使用 Client Credentials 时,通常需要开启 Client authentication。开启这个开关并不表示用户无需登录;是否需要用户登录,取决于应用使用的流程。

Keycloak 的 Authentication Flow 还有另一层含义

在 Client 的配置中,这些开关控制 Client 可以使用哪些协议流程。而 Keycloak 的 Authentication 菜单中,也有 Browser Flow 等内部认证流程。

例如,应用通过 Standard Flow 发起登录后,Keycloak 可以执行 Browser Flow:检查已有会话;如果需要,再展示登录页面,并按配置执行密码、OTP 或其他认证步骤。

前者决定应用如何发起请求,后者决定 Keycloak 如何处理认证。它们可以一起工作。

按场景选择

  • 有后端的 Web 应用:通常开启 Client authentication,使用 Standard Flow,并配合 PKCE。
  • SPA 或手机应用 :通常关闭 Client authentication,使用 Standard Flow 和 PKCE S256。
  • 定时任务或服务间调用:开启 Client authentication 和 Service accounts roles,只分配需要的权限。
  • 输入受限的设备:考虑 Device Authorization Grant,让用户在另一台设备上登录。
  • 需要独立认证渠道的特殊系统:评估 CIBA 和所需的配套组件。

新系统应避免 Direct Access Grants 和 Implicit Flow。无论选择哪种流程,都只启用实际需要的能力,并分别验证 Client 配置、应用集成和目标 API 的授权规则。

相关推荐
运维开发王义杰4 天前
Remote-User 请求头认证:DevSecOps 单点登录的零改造接入与防伪造边界
devsecops
创实信息4 天前
突破SAST瓶颈:解析 SonarQube Hunter Agent 如何检测失效的访问控制与逻辑缺陷
人工智能·ai·devsecops·sonarqube·代码安全
运维开发王义杰10 天前
Cloudflare 开源安全审计 Skill,DevSecOps 可以怎样用?
devsecops
龙智DevSecOps解决方案12 天前
龙智DevSecOps沙龙回顾:JetBrains、JFrog、Perforce、Atlassian五位专家拆解AI研发治理
atlassian·devsecops·jetbrains·jfrog·ai研发治理
运维开发王义杰19 天前
nginx sub_filter:替换了 HTML,也改变了缓存行为
devsecops
运维开发王义杰21 天前
DevOps 和 SRE 怎么区分?从一次服务发布说起
devsecops
研发小能1 个月前
金融行业 DevSecOps 工具链怎么选?面向强合规与私有化的横向比较
研发效能·devsecops·嘉为蓝鲸·金融信创·国产化devops
运维开发王义杰1 个月前
从失控到收敛:全栈生产安全 P1-P4 优先级落地指南
devsecops
Akiyama_Mio-Kon2 个月前
Copilot 现在能批准 PR 了:从“可审”到“可签字”,合并门该怎么重画
devsecops·github copilot·ai agent·代码审查·pull request·分支保护