使用 Auth0 配置 SSO
OpenID Connect(OIDC)在 OAuth 2.0 之上增加了身份层 ,使应用能够验证最终用户的身份,并从身份提供商(IdP)获取基本用户资料。在单点登录(SSO)部署中,用户通过 IdP 完成身份认证后,即可访问已连接的应用,而无需分别登录每个应用。
Auth0 是一个云身份平台,可作为应用和 API 的集中式 IdP。它提供 Universal Login、身份提供商连接、多因素身份认证和访问策略。在本集成中,Apache APISIX 会先将浏览器身份认证委托给 Auth0,再把请求代理到上游服务。
本指南介绍如何配置 APISIX 和 Auth0,以使用带有用于代码交换的证明密钥(PKCE)的 OIDC 授权码流程。当请求没有有效的 APISIX 会话时,APISIX 会将浏览器重定向到 Auth0。身份认证成功后,APISIX 会使用授权码换取 Token、创建浏览器会话,并继续处理原始请求。
前置条件
- 安装 Docker。
- 安装 cURL 和 OpenSSL。
- 按照入门指南使用 Docker 启动 APISIX。
- 拥有 Auth0 租户的管理员权限,以及可通过已启用 Auth0 连接完成身份认证的用户。
- 如果计划使用 ADC,请先安装并配置 ADC。
配置 Auth0
在 Auth0 中注册常规 Web 应用,然后保存其域名和客户端凭证,供 APISIX 路由使用。
创建应用
登录 Auth0 控制台并创建应用:
- 选择 Applications → Applications → Create Application。
- 输入
APISIX Authorization Code作为应用名称。 - 选择 Regular Web Application。
- 选择 Create。
在应用的 Settings 标签页上配置回调:
- 在 Application URIs 下,将
http://localhost:9080/anything/user/callback添加到 Allowed Callback URLs。 - 选择 Save Changes。

回调 URL 用于标识身份认证后 Auth0 将浏览器返回到的 APISIX 端点。在生产环境中,请使用用户可访问的 HTTPS 端点,并在 Auth0 中注册完全相同的 URL。
保存 OIDC 配置
在应用的 Settings 标签页上记录 Domain、Client ID 和 Client Secret。将它们保存到环境变量中,并替换示例值:
export AUTH0_DOMAIN=your-tenant.us.auth0.com
export AUTH0_CLIENT_ID=replace-with-your-client-id
export AUTH0_CLIENT_SECRET=replace-with-your-client-secret
export AUTH0_DISCOVERY="https://${AUTH0_DOMAIN}/.well-known/openid-configuration"
请妥善保管客户端密钥。将生产凭证存储在 Secret 管理器中,并按照组织的凭证轮换策略进行轮换。
配置 APISIX
配置一条路由,在将浏览器请求转发到公共 HTTP 请求与响应服务 httpbin.org 之前执行身份认证。/anything/user/* 端点会返回请求详情以供验证。
生成一个唯一密钥,供 APISIX 加密浏览器会话 Cookie 并验证其完整性:
export APISIX_SESSION_SECRET="$(openssl rand -hex 32)"
选择使用 Admin API 或 ADC 配置路由。
- Admin API
- ADC
通过 Admin API 创建路由:
curl "http://127.0.0.1:9180/apisix/admin/routes/auth0-sso" -X PUT \
--data-binary @- <<EOF
{
"uri": "/anything/user/*",
"plugins": {
"openid-connect": {
"client_id": "$AUTH0_CLIENT_ID",
"client_secret": "$AUTH0_CLIENT_SECRET",
"discovery": "$AUTH0_DISCOVERY",
"redirect_uri": "http://localhost:9080/anything/user/callback",
"bearer_only": false,
"use_pkce": true,
"scope": "openid profile email",
"session": {
"secret": "$APISIX_SESSION_SECRET"
},
"set_access_token_header": false,
"set_id_token_header": false,
"set_userinfo_header": false
},
"proxy-rewrite": {
"headers": {
"remove": ["Authorization", "Cookie"]
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}
EOF
❶ discovery:Auth0 租户的 OIDC 发现文档 URI。
❷ redirect_uri:身份认证后 Auth0 将浏览器返回到的 URI。它必须与 Auth0 中配置的回调 URL 匹配。
❸ bearer_only 和 use_pkce:不存在有效会话时启动浏览器身份认证,并在授权期间发送 S256 PKCE 质询。
❹ set_access_token_header、set_id_token_header 和 set_userinfo_header:设置为 false,防止 APISIX 将 Token 和用户信息添加到上游请求头。
❺ proxy-rewrite.headers.remove:在代理请求前移除原始 Authorization 请求头和整个 Cookie 请求头,包括 APISIX 会话 Cookie。如果上游应用需要 Cookie,请复查此设置。
使用路由配置创建 adc.yaml 文件:
services:
- name: httpbin
routes:
- name: auth0-sso
uris:
- /anything/user/*
plugins:
openid-connect:
client_id: "${AUTH0_CLIENT_ID}"
client_secret: "${AUTH0_CLIENT_SECRET}"
discovery: "${AUTH0_DISCOVERY}"
redirect_uri: http://localhost:9080/anything/user/callback
bearer_only: false
use_pkce: true
scope: openid profile email
session:
secret: "${APISIX_SESSION_SECRET}"
set_access_token_header: false
set_id_token_header: false
set_userinfo_header: false
proxy-rewrite:
headers:
remove:
- Authorization
- Cookie
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
❶ discovery:Auth0 租户的 OIDC 发现文档 URI。
❷ redirect_uri:身份认证后 Auth0 将浏览器返回到的 URI。它必须与 Auth0 中配置的回调 URL 匹配。
❸ bearer_only 和 use_pkce:不存在有效会话时启动浏览器身份认证,并在授权期间发送 S256 PKCE 质询。
❹ set_access_token_header、set_id_token_header 和 set_userinfo_header:设置为 false,防止 APISIX 将 Token 和用户信息添加到上游请求头。
❺ proxy-rewrite.headers.remove:在代理请求前移除原始 Authorization 请求头和整个 Cookie 请求头,包括 APISIX 会话 Cookie。如果上游应用需要 Cookie,请复查此设置。
将配置同步到 APISIX:
adc sync -f adc.yaml
验证身份认证
在浏览器中访问 http://localhost:9080/anything/user/get。APISIX 会将你重定向到 Auth0。如果没有有效的 Auth0 会话,Auth0 会提示你登录。

完成 Auth0 登录。如果 Auth0 要求你授权该应用,请选择 Accept。身份认证成功后,Auth0 会将浏览器返回到 APISIX,APISIX 再把请求转发到 httpbin.org。响应应包含类似以下内容的字段:
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "en-CA,en-US;q=0.9,en;q=0.8",
"Host": "localhost",
"Priority": "u=0, i",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "cross-site",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15",
"X-Amzn-Trace-Id": "Root=1-...",
"X-Forwarded-Host": "localhost:9080"
},
"json": null,
"method": "GET",
"origin": "192.168.155.1, xxx.xxx.xxx.xxx",
"url": "http://localhost:9080/anything/user/get"
}
请求头值和报告的源地址会因浏览器及网络环境而异。
上游请求头不应包含 APISIX 会话 Cookie、访问 Token、ID Token 或用户信息请求头。重新加载页面,验证 APISIX 会复用浏览器会话,而不会将你再次重定向到 Auth0。
后续步骤
你已配置 APISIX 使用 Auth0 对浏览器请求进行身份认证。如需为没有最终用户会话的服务请求授权,请参阅使用 Auth0 为 M2M 请求授权。更多配置选项请参阅 openid-connect 插件参考。