跳到主要内容

使用 Amazon Cognito 配置 SSO

OpenID Connect(OIDC)OAuth 2.0 增加身份层,使应用可以验证最终用户身份,并从身份提供商(IdP)获取基本资料。在单点登录(SSO)部署中,用户通过 IdP 完成身份认证后即可访问关联应用,无需分别登录每个应用。

Amazon Cognito 是 AWS 提供的托管身份服务。Cognito 用户池提供用户目录、OIDC 授权服务器和托管登录页面。在本集成中,Apache APISIX 会先将浏览器身份认证委托给 Cognito,再把请求代理到上游服务。

本指南介绍如何创建 Cognito 用户池和 Web 应用客户端,然后为使用代码交换证明密钥(PKCE)的 OIDC 授权码流程配置 APISIX。当请求没有有效的 APISIX 会话时,APISIX 会将浏览器重定向到 Cognito。身份认证成功后,APISIX 会用授权码换取 Token、创建浏览器会话并继续处理原始请求。

前置条件

配置 Amazon Cognito

为浏览器身份认证流程创建用户池、Web 应用客户端和测试用户。

创建用户池和 Web 应用客户端

登录 AWS 管理控制台,然后打开 Amazon Cognito → User pools。创建用户目录和应用:

  1. 选择 Create user pool
  2. 选择 Traditional web application 作为应用类型。
  3. 输入 APISIX Authorization Code 作为应用名称。
  4. Options for sign-in identifiers 下选择 Email
  5. 除非要允许用户自行创建账户,否则清除 Enable self-registration
  6. 输入 http://localhost:9080/anything/user/callback 作为返回 URL。
  7. 选择 Create user directory

Cognito 会创建用户池、机密应用客户端、用户池 Domain 和托管登录页面。返回 URL 标识 Cognito 完成身份认证后将浏览器发送到的 APISIX 端点。生产环境应使用用户可访问的 HTTPS 端点,并在 Cognito 中注册完全相同的 URL。

在新应用客户端的 Login pages 标签页中,确认 Authorization code grant 是唯一的 OAuth Grant Type,并且允许的 Callback URL 与 APISIX 回调地址一致。

为 APISIX 配置 Cognito 授权码应用客户端

创建用户

创建一个可通过托管登录页面登录的用户:

  1. 在用户池中选择 User management → Users → Create user
  2. Invitation message 保持为不发送邀请的选项。
  3. 输入用户电子邮件地址,然后选择 Mark email address as verified
  4. 设置符合用户池密码策略的临时密码。
  5. 选择 Create user

用户首次登录时必须替换临时密码。

保存 OIDC 配置

在用户池 Overview 页面记录 User pool ID。在 Applications → App clients 下打开 APISIX Authorization Code,并记录其 Client IDClient secret

将示例替换为实际值,并保存为环境变量:

export COGNITO_REGION=ap-southeast-2
export COGNITO_USER_POOL_ID=ap-southeast-2_example
export COGNITO_SSO_CLIENT_ID=replace-with-your-client-id
export COGNITO_SSO_CLIENT_SECRET=replace-with-your-client-secret
export COGNITO_ISSUER="https://cognito-idp.${COGNITO_REGION}.amazonaws.com/${COGNITO_USER_POOL_ID}"
export COGNITO_DISCOVERY="${COGNITO_ISSUER}/.well-known/openid-configuration"

请对客户端密钥保密。生产凭证应存储在密钥管理器中,并按照组织的凭证轮换策略进行轮换。

配置 APISIX

配置一个路由,使其在把请求转发到公共 HTTP 请求和响应服务 httpbin.org 前对浏览器请求进行身份认证。/anything/user/* 端点会返回请求详情以供验证。

生成唯一密钥,供 APISIX 加密并认证浏览器会话 Cookie:

export APISIX_SESSION_SECRET="$(openssl rand -hex 32)"

选择使用 Admin API 或 ADC 配置路由。

通过 Admin API 创建路由:

curl "http://127.0.0.1:9180/apisix/admin/routes/cognito-sso" -X PUT \
--data-binary @- <<EOF
{
"uri": "/anything/user/*",
"plugins": {
"openid-connect": {
"client_id": "$COGNITO_SSO_CLIENT_ID",
"client_secret": "$COGNITO_SSO_CLIENT_SECRET",
"discovery": "$COGNITO_DISCOVERY",
"redirect_uri": "http://localhost:9080/anything/user/callback",
"bearer_only": false,
"use_pkce": true,
"scope": "openid email phone",
"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:Cognito 用户池 OIDC Discovery Document 的 URI。

redirect_uri:Cognito 完成身份认证后将浏览器返回到的 URI。它必须与应用客户端配置的 Callback URL 一致。

bearer_onlyuse_pkce:没有有效会话时启动浏览器身份认证,并在授权过程中发送 S256 PKCE Challenge。

set_access_token_headerset_id_token_headerset_userinfo_header:设为 false,避免 APISIX 把 Token 和用户信息添加到上游请求头。

proxy-rewrite.headers.remove:代理请求前移除原始 Authorization 请求头和整个 Cookie 请求头,包括 APISIX 会话 Cookie。如果上游应用需要 Cookie,请审查此设置。

验证身份认证

在浏览器中访问 http://localhost:9080/anything/user/get。APISIX 会将你重定向到 Cognito 托管登录页面。

使用 Cognito 用户登录。如果是该用户首次登录,请按提示替换临时密码。如果 APISIX 授权会话在登录完成前过期,请重新访问受保护的 URL 以开始新的身份认证流程。详情请参阅找不到会话状态

Cognito 随后将浏览器返回到 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": "none",
"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 会复用浏览器会话,而不会将你再次重定向到 Cognito。

后续步骤

你现在已配置 APISIX 使用 Amazon Cognito 对浏览器请求进行身份认证。如需授权没有最终用户会话的服务请求,请参阅使用 Amazon Cognito 为 M2M 请求授权。有关更多配置选项,请参阅 openid-connect 插件参考