Skip to main content
Version: 3.17

saml-auth

描述#

saml-auth 插件为 API 路由提供 SAML 2.0(安全断言标记语言)身份验证。该插件充当 SAML 服务提供商(SP),并与 Keycloak、Okta、Azure Active Directory 等外部身份提供商(IdP)集成,在允许访问上游资源之前对用户进行身份验证。

当请求到达受保护的路由时,插件会检查是否存在有效的 SAML 会话。若没有会话,则将用户重定向到 IdP 进行身份验证。用户在 IdP 完成认证后,IdP 会将签名的 SAML 断言以 POST 方式发送到 SP 的断言消费者服务(ACS)URL。插件验证断言后,为用户建立会话。

该插件支持:

  • HTTP-Redirect 绑定(默认)— SAML 消息以 URL 查询参数形式传输。
  • HTTP-POST 绑定 — SAML 消息以 HTML 表单值形式传输。
  • 单点注销(SLO) — 注销请求可由 SP 或 IdP 发起。
  • 通过 secret_fallbacks 实现会话密钥轮换

经过身份验证的用户数据存储在 ctx.external_user 中,可供 acl 等下游授权插件使用。

属性#

名称类型必填加密默认值有效值描述
sp_issuerstring服务提供商(SP)实体 ID/颁发者 URI,必须与在 IdP 中注册的 SP 实体 ID 一致。
idp_uristring身份提供商 SSO 端点 URL,SAML 认证请求将发送至此 URL。
idp_certstringPEM 格式的 IdP X.509 证书,用于验证 SAML 断言上的签名。
login_callback_uristringSP 的断言消费者服务(ACS)URL。IdP 在认证后将 SAML 响应 POST 到此 URL,必须在 IdP 中注册。
logout_uristringSP 的单点注销(SLO)端点,请求此 URI 将触发注销流程。
logout_callback_uristringSP 的 SLO 回调 URL,IdP 将注销响应发送至此 URL,必须在 IdP 中注册。
logout_redirect_uristring注销成功后重定向用户的 URL。
sp_certstringPEM 格式的 SP X.509 证书,IdP 使用此证书验证 SP 签名的请求。
sp_private_keystringPEM 格式的 SP 私钥,用于对 SAML 请求进行签名,该字段在存储时加密。
auth_protocol_binding_methodstringHTTP-RedirectHTTP-RedirectHTTP-POST认证请求的 SAML 绑定方式。设置为 HTTP-POST 时,会话 Cookie 的 SameSite 属性将设置为 NoneSecure 设置为 true
secretstring8–32 个字符用于会话密钥派生的密钥。所有 APISIX 节点必须配置相同的值,以确保会话可在多个 worker 进程之间及重启后正常读取。该字段在存储时加密。
secret_fallbacksarray[string]每项:8–32 个字符密钥轮换时使用的历史密钥列表,允许使用旧密钥加密的会话继续有效,该字段在存储时加密。

前提条件#

在启用该插件前,请先在每个 APISIX 节点上安装 lua-resty-saml

luarocks install lua-resty-saml 0.2.5

lua-resty-saml 会编译原生 xmlsec 绑定,因此构建环境需要提供 LuaRocks 所需的 OpenSSL、libxml2 和 libxslt 开发文件。

在配置 saml-auth 插件之前,需要在身份提供商处将 APISIX 注册为服务提供商。具体步骤因 IdP 而异,以下示例使用 Keycloak

配置 Keycloak#

  1. 登录 Keycloak 管理控制台。
  2. 创建或选择一个 Realm(例如 myrealm)。
  3. 进入 Clients,点击 Create client
  4. Client type 设置为 SAML
  5. Client ID 设置为与插件配置中 sp_issuer 一致的值(例如 https://sp.example.com)。
  6. Client > Settings 中:
    • Root URL 设置为 https://sp.example.com
    • Valid redirect URIs 设置为包含 login_callback_uri(例如 https://sp.example.com/login/callback)。
    • Master SAML Processing URL 设置为 https://sp.example.com/login/callback
  7. Client > Keys 中,上传 SP 证书(sp_cert)并启用 Sign assertions
  8. 导出 IdP 元数据,获取 idp_uri(SSO URL)和 idp_cert(签名证书)。
  9. 在 Keycloak 中创建允许登录的用户。

启用插件#

以下示例创建一个使用 Keycloak IdP 的 saml-auth 插件保护的路由:

note

请将证书和密钥占位符替换为实际的 SP 证书、SP 私钥和 IdP 证书。

curl "http://127.0.0.1:9180/apisix/admin/routes/1" \
-H "X-API-KEY: $ADMIN_API_KEY" \
-X PUT \
-d '{
"uri": "/*",
"plugins": {
"saml-auth": {
"sp_issuer": "https://sp.example.com",
"idp_uri": "https://keycloak.example.com/realms/myrealm/protocol/saml",
"idp_cert": "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----",
"login_callback_uri": "https://sp.example.com/login/callback",
"logout_uri": "https://sp.example.com/logout",
"logout_callback_uri": "https://sp.example.com/logout/callback",
"logout_redirect_uri": "https://sp.example.com/logout/done",
"sp_cert": "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----",
"sp_private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIE...\n-----END RSA PRIVATE KEY-----",
"auth_protocol_binding_method": "HTTP-Redirect",
"secret": "my-session-secret"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'

禁用插件#

如需禁用 saml-auth 插件,从路由配置中移除即可:

curl "http://127.0.0.1:9180/apisix/admin/routes/1" \
-H "X-API-KEY: $ADMIN_API_KEY" \
-X PUT \
-d '{
"uri": "/*",
"plugins": {},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:1980": 1
}
}
}'