创建 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 的授权规则。