设置 Amazon Cognito 单点登录
OpenID Connect (OIDC) 是位于 OAuth 2.0 协议 之上的简单身份层。它允许客户端根据身份提供商执行的身份验证来验证最终用户的身份,并以可互操作和类似 REST 的方式获取有关最终用户的基本个人资料信息。
Amazon Cognito 是 AWS 提供的一项完全托管的服务,简化了向应用程序添加身份验证和身份管理的过程。通过利用 Cognito 进行单点登录,组织可以增强安全性,简化用户体验,并减少管理多个凭证的负担。
本指南将向你展示如何将 APISIX 与 Amazon Cognito 集成以实施 授权码授予 和 客户端凭证授予。
前置条件
实施授权码授予
授权码授予用于 Web 和移动应用程序。该流程从授权服务器在浏览器中显示登录页面开始,用户可以在其中输入凭证。在此过程中,短期授权码将交换为访问令牌,APISIX 将其存储在浏览器会话 cookie 中,并将随访问上游资源服务器的每个请求一起发送。
创建用户池 和应用程序客户端
用户池是一个用户目录,你可以在其中添加更多应用程序(应用程序客户端)并设置身份验证、安全性和身份验证 UI。
登录 AWS 控制台并导航到 Amazon Cognito 服务。在 user pools 下,单击 create user pool。此过程将创建一个用户池以及一个应用程序,你以后仍可以对其进行更新。在设置期间:
- 选择 traditional web applications 作为应用程序类型。
- 输入应用程序名称,例如
apisix-app。 - 在 options for sign-in identifiers 下,选中 email 选项。
- 在 required attributes for sign-up 下,选择 email、family name 和 given name。当用户首次登录时,系统将提示他们更改密码并提供所需的属性。根据你的用例进行相应调整。
- 在 return URL 下,输入
http://localhost:9080/anything/callback作为回调 URL。
请注意,应用程序客户端创建后,无法更改登录标识符和所需属性的选项。
完成用户池和应用程序客户端的创建。
获取集成配置
导航到新创建的用户池,然后单击 Applications > App clients。单击进入应用程序客户端并找到客户端 ID 和 secret:

向下滚动到快速设置指南,你可以在其中找到 issuer URL:

将这些信息保存到环境变量中:
# 替换为你的配置值
export COGNITO_CLIENT_ID=58qa9qdqcub787lf1ohq4fqn7f
export COGNITO_CLIENT_SECRET=ohtgsk1mkii53vs2m3f7l7ln05foktjf5jso8mce2alahnabpku
export COGNITO_ISSUER_URL=https://cognito-idp.ap-northeast-3.amazonaws.com/ap-northeast-3_mSfuhPzhm
export COGNITO_DISCOVERY="${COGNITO_ISSUER_URL}/.well-known/openid-configuration"
创建用户
导航到用户池,在 User management 下,选择 Users。创建一个新用户:

输入电子邮件地址、电话号码、首次密码,然后创建用户:

你可以根据你的用户群创建更多用户。
配置 APISIX
在本节中,你将创建一个带有 OIDC 的路由,该路由将客户端请求转发到 httpbin.org,这是一个公共 HTTP 请求和响应服务。httpbin.org 的路由 /anything/{anything} 以 JSON 类型返回请求数据中传递的任何内容,例如方法、参数和标 头。
创建带有 openid-connect 插件的路由,如下所示:
- Admin API
- ADC
- Ingress Controller
curl -i "http://127.0.0.1:9180/apisix/admin/routes" -X PUT -d '
{
"id": "auth-with-oidc",
"uri":"/anything/*",
"plugins": {
"openid-connect": {
// Annotate 1
"client_id": "'"$COGNITO_CLIENT_ID"'",
// Annotate 2
"client_secret": "'"$COGNITO_CLIENT_SECRET"'",
// Annotate 3
"discovery": "'"$COGNITO_DISCOVERY"'",
// Annotate 4
"scope": "openid email phone",
// Annotate 5
"redirect_uri": "http://localhost:9080/anything/callback",
// Annotate 6
"bearer_only": false,
"session": {
// Annotate 7
"secret": "f86cf31663a9c9fa0a28c2cc78badef1"
}
}
},
"upstream": {
"type":"roundrobin",
"nodes": {
"httpbin.org:80":1
}
}
}'
❶ client_id:Cognito 客户端 ID。
❷ client_secret:Cognito 客户端 secret。
❸ discovery:发现文档的 URI。
❹ scope:定义与应用程序客户端中定义的范围相对应的范围。你可以在应用程序客户端的 Login pages 选项卡下仔细检查范围。
❺ redirect_uri:身份验证后重定向的 URI。
❻ bearer_only:对于授权码授予,设置为 false。
❼ session.secret:替换为你用于会话加密和 HMAC 操作的密钥。当 bearer_only 为 false 时为必需。
services:
- name: httpbin Service
routes:
- uris:
- /anything/*
name: auth-with-oidc
plugins:
openid-connect:
// Annotate 1
client_id: '58qa9qdqcub787lf1ohq4fqn7f'
// Annotate 2
client_secret: ohtgsk1mkii53vs2m3f7l7ln05foktjf5jso8mce2alahnabpku
// Annotate 3
discovery: https://cognito-idp.ap-northeast-3.amazonaws.com/ap-northeast-3_mSfuhPzhm/.well-known/openid-configuration
// Annotate 4
scope: openid email phone
// Annotate 5
redirect_uri: http://localhost:9080/anything/callback
// Annotate 6
bearer_only: false
session:
// Annotate 7
secret: f86cf31663a9c9fa0a28c2cc78badef1
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
❶ client_id:Cognito 客户端 ID。
❷ client_secret:Cognito 客户端 secret。
❸ discovery:发现文档的 URI。
❹ scope:定义与应用程序客户端中定义的范围相对应的范围。你可以在应用程序客户端的 Login pages 选项卡下仔细检查范围。
❺ redirect_uri:身份验证后重定向的 URI。
❻ bearer_only:对于授权码授予,设置为 false。
❼ session.secret:替换为你用于会话加密和 HMAC 操作的密钥。当 bearer_only 为 false 时为必需。
将配置同步到 APISIX:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: ingress-apisix
name: auth-plugin-config
spec:
plugins:
- name: openid-connect
config:
// Annotate 1
client_id: 58qa9qdqcub787lf1ohq4fqn7f
// Annotate 2
client_secret: ohtgsk1mkii53vs2m3f7l7ln05foktjf5jso8mce2alahnabpku
// Annotate 3
discovery: https://cognito-idp.ap-northeast-3.amazonaws.com/ap-northeast-3_mSfuhPzhm/.well-known/openid-configuration
// Annotate 4
scope: openid email phone
// Annotate 5
redirect_uri: http://localhost:9080/anything/callback
// Annotate 6
bearer_only: false
session:
// Annotate 7
secret: f86cf31663a9c9fa0a28c2cc78badef1
---
apiVersion: v1
kind: Service
metadata:
namespace: ingress-apisix
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: ingress-apisix
name: auth-with-oidc
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: PathPrefix
value: /anything/*
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: auth-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: ingress-apisix
name: httpbin-external-domain
spec:
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: ingress-apisix
name: auth-with-oidc
spec:
ingressClassName: apisix
http:
- name: auth-with-oidc
match:
paths:
- /anything/*
plugins:
- name: openid-connect
enable: true
config:
// Annotate 1
client_id: 58qa9qdqcub787lf1ohq4fqn7f
// Annotate 2
client_secret: ohtgsk1mkii53vs2m3f7l7ln05foktjf5jso8mce2alahnabpku
// Annotate 3
discovery: https://cognito-idp.ap-northeast-3.amazonaws.com/ap-northeast-3_mSfuhPzhm/.well-known/openid-configuration
scope: openid email phone
redirect_uri: http://localhost:9080/anything/callback
bearer_only: false
session:
secret: f86cf31663a9c9fa0a28c2cc78badef1
upstreams:
- name: httpbin-external-domain
❶ client_id:Cognito 客户端 ID。
❷ client_secret:Cognito 客户端 secret。
❸ discovery:发现文档的 URI。
❹ scope:定义与应用程序客户端中定义的范围相对应的范围。你可以在应用程序客户端的 Login pages 选项卡下仔细检查范围。
❺ redirect_uri:身份验证后重定向的 URI。
❻ bearer_only:对于授权码授予,设置为 false。
❼ session.secret:替换为你用于会话加密和 HMAC 操作的密钥。当 bearer_only 为 false 时为必需。
将配置应用到你的集群:
kubectl apply -f oidc-route.yaml
验证
在浏览器中导航到 http://localhost:9080/anything/test。你应该被重定向到登录页面:

使用用户凭证登录。如果是第一次登录,系统会提示你更改密码,并提供姓氏和名字,如之前在所需属性中配置的那样。
如果成功,请求将被转发到 httpbin.org