🤔 Introducing APISIX AI Gateway – Built for LLMs and AI workloads. Learn More

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
      }
    }
  }'