跳到主要内容

设置 Amazon Cognito 单点登录

OpenID Connect (OIDC) 是位于 OAuth 2.0 协议 之上的简单身份层。它允许客户端根据身份提供商执行的身份验证来验证最终用户的身份,并以可互操作和类似 REST 的方式获取有关最终用户的基本个人资料信息。

Amazon Cognito 是 AWS 提供的一项完全托管的服务,简化了向应用程序添加身份验证和身份管理的过程。通过利用 Cognito 进行单点登录,组织可以增强安全性,简化用户体验,并减少管理多个凭证的负担。

本指南将向你展示如何将 APISIX 与 Amazon Cognito 集成以实施 授权码授予客户端凭证授予

前置条件

  • 安装 Docker
  • 安装 cURL 以向服务发送请求进行验证。
  • 按照 快速入门教程 在 Docker 或 Kubernetes 中启动一个新的 APISIX 实例。
  • 创建一个 AWS 帐户。

实施授权码授予

授权码授予用于 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 下,选择 emailfamily namegiven name。当用户首次登录时,系统将提示他们更改密码并提供所需的属性。根据你的用例进行相应调整。
  • return URL 下,输入 http://localhost:9080/anything/callback 作为回调 URL。

请注意,应用程序客户端创建后,无法更改登录标识符和所需属性的选项。

完成用户池和应用程序客户端的创建。

获取集成配置

导航到新创建的用户池,然后单击 Applications > App clients。单击进入应用程序客户端并找到客户端 ID 和 secret:

app client

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

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。创建一个新用户:

create a new user

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

user details

你可以根据你的用户群创建更多用户。

配置 APISIX

在本节中,你将创建一个带有 OIDC 的路由,该路由将客户端请求转发到 httpbin.org,这是一个公共 HTTP 请求和响应服务。httpbin.org 的路由 /anything/{anything} 以 JSON 类型返回请求数据中传递的任何内容,例如方法、参数和标头。

创建带有 openid-connect 插件的路由,如下所示:

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_onlyfalse 时为必需。

验证

在浏览器中导航到 http://localhost:9080/anything/test。你应该被重定向到登录页面:

Amazon Cognito 登录页面

使用用户凭证登录。如果是第一次登录,系统会提示你更改密码,并提供姓氏和名字,如之前在所需属性中配置的那样。

如果成功,请求将被转发到 httpbin.org,你应该看到类似以下的响应:

{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "text/html..."
...
},
"json": null,
"method": "GET",
"origin": "127.0.0.1, 59.71.xxx.xxx",
"url": "http://127.0.0.1/anything/test"
}

实施客户端凭证授予

在客户端凭证授予中,客户端在没有任何用户参与的情况下获取访问令牌。它通常用于机器对机器 (M2M) 通信。

创建用户池和应用程序客户端

登录 AWS 控制台并导航到 Amazon Cognito 服务。如果你已经有一个用户池并希望在同一池中创建一个应用程序客户端,请导航到该用户池并选择 create app client。否则,在 user pools 下,单击 create user pool。此过程将创建一个用户池以及一个应用程序,你以后仍可以对其进行更新。在设置期间:

  • 选择 machine-to-machine application 作为应用程序类型。
  • 输入应用程序名称,例如 apisix-app-m2m

完成创建应用程序客户端。你应该会看到生成的快速设置指南。复制 curl 命令,该命令将在验证步骤中用于获取访问令牌。你的命令应类似于以下内容:

curl -X POST "https://ap-northeast-3msfuhpzhm.auth.ap-northeast-3.amazoncognito.com/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=1nh91q0q1bgimb7pc79uh2btqe&client_secret=<client secret>&scope=default-m2m-resource-server-hlyky3/read"

获取集成配置

在用户池中,记下用户池 ID 和令牌签名密钥 URL 域。将它们组合为 authority URL 和发现文档 URL:

# 替换为你的配置值
export COGNITO_USER_POOL_ID=ap-northeast-3_mSfuhPzhm
export COGNITO_AUTHORITY_URL="https://cognito-idp.ap-northeast-3.amazonaws.com/${COGNITO_USER_POOL_ID}"
export COGNITO_DISCOVERY="${COGNITO_AUTHORITY_URL}/.well-known/openid-configuration"

单击 Applications > App clients。导航到应用程序客户端并找到客户端 ID 和 secret:

app client

将这些信息保存到环境变量中:

# 替换为你的配置值
export COGNITO_CLIENT_ID=1nh91q0q1bgimb7pc79uh2btqe
export COGNITO_CLIENT_SECRET=133cbobt7c9lu372u9tf3kh2p0laj0krtrfkqne3c4kao2hn69k1

配置 APISIX

要实施客户端凭证授予,请创建一个带有 openid-connect 插件的路由,如下所示:

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
"use_jwks": true,
"client_id": "'"$COGNITO_CLIENT_ID"'",
"client_secret": "'"$COGNITO_CLIENT_SECRET"'",
"discovery": "'"$COGNITO_DISCOVERY"'",
"scope": "openid email phone",
"redirect_uri": "http://localhost:9080/anything/callback",
"bearer_only": false,
"session": {
"secret": "f86cf31663a9c9fa0a28c2cc78badef1"
}
}
},
"upstream": {
"type":"roundrobin",
"nodes": {
"httpbin.org:80":1
}
}
}'

❶ 使用身份提供商的 JWKS 端点验证令牌。端点从发现文档中获取。

验证

使用你之前保存的命令获取访问令牌:

curl -X POST "https://ap-northeast-3msfuhpzhm.auth.ap-northeast-3.amazoncognito.com/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=1nh91q0q1bgimb7pc79uh2btqe&client_secret=<client secret>&scope=default-m2m-resource-server-hlyky3/read"

预期的响应类似于以下内容:

eyJraWQiOiJoOGhya3pDVkx4Y1ZUaXJONmZKZ2FtbjFScGtKNTBsQVV2cDRzdDEzbkJjPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIxbmg5MXEwcTFiZ2ltYjdwYzc5dWgyYnRxZSIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiZGVmYXVsdC1tMm0tcmVzb3VyY2Utc2VydmVyLWhseWt5M1wvcmVhZCIsImF1dGhfdGltZSI6MTczMzM4NDE0NCwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLmFwLW5vcnRoZWFzdC0zLmFtYXpvbmF3cy5jb21cL2FwLW5vcnRoZWFzdC0zX21TZnVoUHpobSIsImV4cCI6MTczMzM4Nzc0NCwiaWF0IjoxNzMzMzg0MTQ0LCJ2ZXJzaW9uIjoyLCJqdGkiOiJmMmMxOWFjNy04YWNmLTQ3NDUtYjQ4MS05MDFkZDFhZWM2OTMiLCJjbGllbnRfaWQiOiIxbmg5MXEwcTFiZ2ltYjdwYzc5dWgyYnRxZSJ9.a89gU2BYFGX-qKMx85ZBMQ8Ik1FWekg1Ci-0z5d6MMTiV0AWfY17nxrD9nbSxNyrxzm1dVU4Ah6nOaqwqnBfUMplfy0FL3L-YmFjNoTzGe3NIFGZe4QjZcubf--r5Px7kY2ESsYZgNCUX6v5X123uuHfqG0Ugd0nkFWUKIbAYjVjlAzBpnQh2nqhg0Q99Bm-QSYZM4pM8ClxZ1haaOL8f1WrlGwRUAqYmEgeU4M0ldIi-7Oe0vhXsW8sK6c3Wdd6aH0z2L-9lgj7n9sw5gDlq6yy5lvmDKnZy-lSGo_9i-h7XVk2WdYKf1pF5IBpBboiEtBvPrZXCK_L8lK2GshdMg","expires_in":3600,"token_type":"Bearer"}

将访问令牌保存到环境变量:

# 替换为你的访问令牌
export ACCESS_TOKEN=eyJraWQiOiJoOGhya3pDVkx4Y1ZUaXJONmZKZ2FtbjFScGtKNTBsQVV2cDRzdDEzbkJjPSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiIxbmg5MXEwcTFiZ2ltYjdwYzc5dWgyYnRxZSIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiZGVmYXVsdC1tMm0tcmVzb3VyY2Utc2VydmVyLWhseWt5M1wvcmVhZCIsImF1dGhfdGltZSI6MTczMzM4NDE0NCwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLmFwLW5vcnRoZWFzdC0zLmFtYXpvbmF3cy5jb21cL2FwLW5vcnRoZWFzdC0zX21TZnVoUHpobSIsImV4cCI6MTczMzM4Nzc0NCwiaWF0IjoxNzMzMzg0MTQ0LCJ2ZXJzaW9uIjoyLCJqdGkiOiJmMmMxOWFjNy04YWNmLTQ3NDUtYjQ4MS05MDFkZDFhZWM2OTMiLCJjbGllbnRfaWQiOiIxbmg5MXEwcTFiZ2ltYjdwYzc5dWgyYnRxZSJ9.a89gU2BYFGX-qKMx85ZBMQ8Ik1FWekg1Ci-0z5d6MMTiV0AWfY17nxrD9nbSxNyrxzm1dVU4Ah6nOaqwqnBfUMplfy0FL3L-YmFjNoTzGe3NIFGZe4QjZcubf--r5Px7kY2ESsYZgNCUX6v5X123uuHfqG0Ugd0nkFWUKIbAYjVjlAzBpnQh2nqhg0Q99Bm-QSYZM4pM8ClxZ1haaOL8f1WrlGwRUAqYmEgeU4M0ldIi-7Oe0vhXsW8sK6c3Wdd6aH0z2L-9lgj7n9sw5gDlq6yy5lvmDKnZy-lSGo_9i-h7XVk2WdYKf1pF5IBpBboiEtBvPrZXCK_L8lK2GshdMg

使用有效访问令牌向路由发送请求:

curl -i "http://127.0.0.1:9080/anything/test" -H "Authorization: Bearer $ACCESS_TOKEN"

你应该收到来自上游服务的 HTTP/1.1 200 OK 响应。

使用无效访问令牌向路由发送请求:

curl -i "http://127.0.0.1:9080/anything/test" -H "Authorization: Bearer invalid_token"

你应该收到 HTTP/1.1 401 Unauthorized 响应。

下一步

APISIX 支持与许多其他 OIDC 身份提供商集成,例如 OktaKeycloakAuthgearMicrosoft Entra ID (Azure AD)Google

此外,APISIX 还支持内置身份验证方法,例如 密钥认证基本认证JWT 认证HMAC 认证