跳到主要内容

openid-connect

openid-connect 插件支持与 OpenID Connect (OIDC) 身份提供商(IdP)集成,例如 KeycloakAuth0Microsoft Entra IDGoogleAmazon CognitoOkta 等。它允许 APISIX 在允许或拒绝客户端访问上游受保护资源之前,对其进行身份验证并从身份提供商获取其信息。

示例

授权码流程

授权码流程在 RFC 6749, Section 4.1 中定义。它涉及将临时授权码交换为访问令牌,通常用于机密客户端和公共客户端。

下图说明了在实现授权码流程时不同实体之间的交互:


当传入请求的头部或适当的会话 Cookie 中不包含访问令牌时,插件将充当依赖方并重定向到授权服务器以继续授权码流程。

身份验证成功后,插件将令牌保存在会话 Cookie 中,后续请求将使用存储在 Cookie 中的令牌。

参见 实施授权码授予 了解如何使用 openid-connect 插件通过授权码流程与 Keycloak 集成的示例。

用于代码交换的证明密钥 (PKCE)

用于代码交换的证明密钥 (PKCE) 在 RFC 7636 中定义。PKCE 通过添加代码挑战和验证器来增强授权码流程,以防止授权码拦截攻击。

下图说明了在实现带有 PKCE 的授权码流程时不同实体之间的交互:


参见 实施授权码授予 了解如何使用 openid-connect 插件通过带有 PKCE 的授权码流程与 Keycloak 集成的示例。

客户端凭据流程

客户端凭据流程在 RFC 6749, Section 4.4 中定义。它涉及客户端使用自己的凭据请求访问令牌以访问受保护资源,通常用于机器对机器的身份验证,不代表特定用户。

下图说明了在实现客户端凭据流程时不同实体之间的交互:


参见 实施客户端凭据授予 了解如何使用 openid-connect 插件通过客户端凭据流程与 Keycloak 集成的示例。

内省流程

内省流程在 RFC 7662 中定义。它涉及通过查询授权服务器的内省端点来验证访问令牌的有效性和详细信息。

在此流程中,当客户端向资源服务器出示访问令牌时,资源服务器向授权服务器的内省端点发送请求,如果令牌处于活动状态,该端点将响应令牌详细信息,包括令牌过期时间、关联的范围以及它所属的用户或客户端等信息。

下图说明了在实现带有令牌内省的授权码流程时不同实体之间的交互:


参见 实施客户端凭据授予 了解如何使用 openid-connect 插件通过带有令牌内省的客户端凭据流程与 Keycloak 集成的示例。

密码流程

密码流程在 RFC 6749, Section 4.3 中定义。它专为受信任的应用程序设计,允许它们直接使用用户的用户名和密码获取访问令牌。在这种授予类型中,客户端应用程序将用户的凭据连同其自己的客户端 ID 和密钥发送到授权服务器,授权服务器随后对用户进行身份验证,如果验证通过,则颁发访问令牌。

虽然效率很高,但此流程仅适用于高度受信任的第一方应用程序,因为它要求应用程序直接处理敏感的用户凭据,如果在第三方上下文中使用,会带来重大的安全风险。

下图说明了在实现密码流程时不同实体之间的交互:


参见 实施密码授予 了解如何使用 openid-connect 插件通过密码流程与 Keycloak 集成的示例。

刷新令牌授予

刷新令牌授予在 RFC 6749, Section 6 中定义。它使客户端能够在无需用户重新身份验证的情况下,使用以前颁发的刷新令牌请求新的访问令牌。此流程通常在访问令牌过期时使用,允许客户端在无需用户干预的情况下保持对资源的持续访问。刷新令牌在某些 OAuth 流程中与访问令牌一起颁发,其生命周期和安全要求取决于授权服务器的配置。

下图说明了在实现带有刷新令牌流程的密码流程时不同实体之间的交互:


参见 刷新令牌 了解如何使用 openid-connect 插件通过带有令牌刷新的密码流程与 Keycloak 集成的示例。

用户信息

OpenID Connect (OIDC) 中的 UserInfo 端点在 OpenID Connect Core 1.0, Section 5.3 中定义。它使客户端能够通过出示有效的访问令牌来检索有关已认证用户的其他 Claim。此端点对于在用户通过身份验证后获取用户个人资料信息(如姓名、电子邮件和其他属性)特别有用。UserInfo 端点返回的数据取决于访问令牌的范围和授权服务器配置的 Claim。

下图说明了当 APISIX 验证用户信息时不同实体之间的交互:


参见 通过检查来自外部身份提供商的用户信息来控制访问 了解如何使用 openid-connect 插件与 Keycloak 集成,并基于用户信息使用企业版 acl 插件实现访问控制的示例。

故障排除

本节涵盖了在使用此插件时常见的一些问题,以帮助您进行故障排除。

APISIX 无法连接到 OpenID 提供商

如果 APISIX 无法解析或无法连接到 OpenID 提供商,请仔细检查配置文件 config.yaml 中的 DNS 设置,并根据需要进行修改。

找不到会话状态 (No Session State Found)

如果您在使用 授权码流程 时遇到 500 internal server error 并在日志中看到以下消息,可能有多种原因。

the error request to the redirect_uri path, but there's no session state found

1. 重定向 URI 配置错误

一个常见的错误配置是将 redirect_uri 配置为与路由的 URI 相同。当用户发起访问受保护资源的请求时,请求直接命中重定向 URI,而请求中没有会话 Cookie,这会导致找不到会话状态的错误。

要正确配置重定向 URI,请确保 redirect_uri 与配置了插件的路由匹配,但不要完全相同。例如,正确的配置是将路由的 uri 配置为 /api/v1/*,并将 redirect_uri 的路径部分配置为 /api/v1/redirect

您还应确保 redirect_uri 包含协议方案,例如 httphttps

2. 缺少 Session Secret

如果您在 Standalone 模式 下部署 APISIX,请确保已配置 session.secret

用户会话作为 Cookie 存储在浏览器中,并使用会话密钥加密。如果没有通过 session.secret 属性配置密钥,该密钥将自动生成并保存到 etcd。但是,在 Standalone 模式下,etcd 不再是配置中心。因此,您应该在 YAML 配置中心 apisix.yaml 中为该插件显式配置 session.secret

检查 SameSite Cookie 属性是否设置正确(即,如果您的应用程序需要跨站点发送 Cookie),以查看这是否是阻止 Cookie 保存到浏览器 Cookie 存储或从浏览器发送的因素。

4. 上游发送的头部过大

如果您的 APISIX 前面有 NGINX 代理客户端流量,请查看 NGINX 的 error.log 中是否观察到以下错误:

upstream sent too big header while reading response header from upstream

如果是这样,请尝试将 proxy_buffersproxy_buffer_sizeproxy_busy_buffers_size 调整为更大的值。

或者,调整插件的 session_contents 参数以仅包含必要的信息。例如,要仅包含访问令牌和刷新令牌,您可以按如下方式配置插件:

{
...
"plugins": {
"openid-connect": {
...,
"session_contents": {
"access_token": true
}
}
}
}

可用选项包括 id_tokenuserenc_id_tokenaccess_token(其中包括刷新令牌)。未配置时,所有内容都包含在会话中。

5. 无效的客户端密钥

验证 client_secret 是否有效且正确。无效的 client_secret 将导致身份验证失败,并且不会返回令牌并存储在会话中。

6. PKCE IdP 配置

如果您正在启用带有授权码流程的 PKCE,请确保您已将 IdP 客户端配置为使用 PKCE。例如,在 Keycloak 中,您应该在客户端的高级设置中配置 PKCE 挑战方法:

PKCE keycloak configuration