跳到主内容

APISIX

可以用两种方式以 Casdoor 保护 Apache APISIX 后面的 API:

  • 使用 APISIX 专门的 authz-casdoor 插件,走基于浏览器的 OAuth 2.0 授权码流程和基于会话的认证。
  • 需要标准 OIDC 功能,或者要显式传递身份和令牌时,使用 APISIX 的 openid-connect 插件配合 Casdoor 的 OpenID Connect 发现地址。

通过 APISIX 的 Casdoor 插件连接 Casdoor​

authz-casdoor 插件会把未认证的浏览器请求跳转到 Casdoor,已认证的会话则可以访问上游 API。 OAuth 2.0 回调由 APISIX 处理,上游应用无需实现授权码流程。

先决条件​

配置插件前,先准备:

  • 一个运行中的 Casdoor,以及包含 authz-casdoor 的 Apache APISIX 版本。
  • 一个 Casdoor 应用,其 Redirect URL 与你要配置的 callback_url 完全一致。
  • 该 Casdoor 应用的 Client ID 和 Client Secret。
  • 一条 APISIX Route,其 URI 同时匹配受保护的路径和回调路径。

启用插件​

把 APISIX Admin API 密钥存到环境变量中,然后创建一条启用了 authz-casdoor 的 Route。把示例中的主机名和凭据换成你环境中的值。

export APISIX_ADMIN_KEY="<APISIX_ADMIN_KEY>"

curl "http://127.0.0.1:9180/apisix/admin/routes/1" \
-H "X-API-KEY: ${APISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-X PUT \
--data '
{
"methods": ["GET"],
"uri": "/anything/*",
"plugins": {
"authz-casdoor": {
"endpoint_addr": "https://casdoor.example.com",
"callback_url": "https://gateway.example.com/anything/callback",
"client_id": "<CASDOOR_CLIENT_ID>",
"client_secret": "<CASDOOR_CLIENT_SECRET>"
}
},
"upstream": {
"scheme": "https",
"type": "roundrobin",
"nodes": {
"<UPSTREAM_HOST>:443": 1
}
}
}'

这个示例保护 /anything/*,把 <UPSTREAM_HOST> 替换后,已授权的请求会转发到你自己的 HTTPS 上游。回调路径 /anything/callback 也在同一条 Route 中,这样插件才能处理 Casdoor 的授权响应。

注意事项

生产环境配置

endpoint_addr 和 callback_url 使用 HTTPS。不要把 APISIX Admin API 密钥或 Casdoor Client Secret 提交到代码仓库,并在日志中脱敏授权码、令牌和会话 Cookie。

使用可信的 HTTPS 上游。插件不会添加 Casdoor 令牌或身份请求头,但浏览器原始的 Cookie 请求头(包括 APISIX 会话 Cookie)如果不移除,会继续传到上游。上游应用不需要它时,在代理前移除或过滤这个请求头。

在生产环境使用前,用你实际部署的 APISIX 版本和 worker 拓扑完整验证登录、回调和会话流程。不同版本的会话行为可能不同。

属性​

名称类型申请标准描述
endpoint_addr字符串必填Casdoor 部署的基础地址。
client_id字符串必填Casdoor 应用的 Client ID。
client_secret字符串必填Casdoor 应用的 Client Secret。
callback_url字符串必填接收授权响应的回调地址。

endpoint_addr 和 callback_url 不能以 / 结尾。 callback_url 中的路径必须被 APISIX Route 匹配,因为插件在把请求代理到上游之前处理回调。

如果 APISIX 启用了 加密存储字段,插件的 client_secret 会加密存储在 etcd 中。

理解授权流程​

  1. 未认证的浏览器请求受保护的 Route 时,插件会创建会话,保存原始请求路径和 state 值,然后把浏览器跳转到 Casdoor。
  2. 认证后,Casdoor 带着 code 和 state 参数把浏览器跳转到 callback_url。插件校验 state,并用授权码换取访问令牌。
  3. 插件把访问令牌保存在 APISIX 会话中,再把浏览器跳回原始请求路径。插件只保存路径,不保存原始查询字符串,所以应用不应依赖登录后恢复查询参数。
  4. 之后带有有效会话的请求可以直接访问上游 API,不会再跳转登录。

authz-casdoor 插件用访问令牌建立 APISIX 会话。它不会自动把 Casdoor 的 Access Token、ID Token 或用户身份加到上游请求头中。如果上游服务需要显式传递令牌或身份,使用下面的 openid-connect 集成。

通过 APISIX 的 OIDC 插件连接 Casdoor​

Casdoor可以使用OIDC协议连接到APISIX,本文档将向您展示如何操作。

以下是配置中使用的一些名称:

CASDOOR_HOSTNAME:部署Casdoor服务器的域名或IP。

APISIX_HOSTNAME: 部署 APISIX 的域名或 IP。

步骤1:部署Casdoor和APISIX​

部署 Casdoor 和 APISIX。部署后,确认:

  1. 可以登录并正常使用Casdoor。
  2. 将Casdoor的 origin 值 (conf/app.conf) 设置为 CASDOOR_HOSTNAME。 Casdoor 配置

步骤2:配置Casdoor应用程序​

  1. 创建一个新的Casdoor应用程序,或使用一个已经存在的。
  2. 添加回调地址:https://APISIX_HOSTNAME/REDIRECTWHATYOUWANT,并把 REDIRECTWHATYOUWANT 换成你想要的回调路径。
  3. 选择 "JWT-Empty" 作为令牌格式选项。
  4. 添加所需的提供商并配置其他设置。

应用程序设置 记下 Client ID 和 Client Secret,下一步要用。 OIDC 发现地址:https://<CASDOOR_HOSTNAME>/.well-known/openid-configuration。

步骤3:配置APISIX​

APISIX 拥有官方 OIDC 支持,由 lua-resety-openidc 实现。

按 APISIX OIDC 自定义设置。路由示例:

export APISIX_ADMIN_KEY="<APISIX_ADMIN_KEY>"

curl "http://127.0.0.1:9180/apisix/admin/routes" \
-H "X-API-KEY: ${APISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-X POST \
--data '
{
"uri": "/get",
"name": "apisix_casdoor_test",
"plugins": {
"openid-connect": {
"client_id": "<CASDOOR_CLIENT_ID>",
"client_secret": "<CASDOOR_CLIENT_SECRET>",
"discovery": "https://CASDOOR_HOSTNAME/.well-known/openid-configuration",
"introspection_endpoint_auth_method": "client_secret_basic",
"logout_path": "/logout",
"realm": "master",
"redirect_uri": "https://APISIX_HOSTNAME/REDIRECTWHATYOUWANT",
"bearer_only": false,
"set_id_token_header": false,
"access_token_in_authorization_header": true,
"set_access_token_header": true,
"set_userinfo_header": false
}
},
"upstream": {
"scheme": "https",
"type": "roundrobin",
"nodes": {
"<UPSTREAM_HOST>:443": 1
}
}
}'

这个 OIDC 配置会把访问令牌转发给上游,所以要把 <UPSTREAM_HOST> 换成可信的 HTTPS 服务。访问 https://APISIX_HOSTNAME/get,浏览器会跳转到 Casdoor 登录页。登录后,请求会转发到配置的上游。下面的截图是一个响应示例。 APISIX_Result