跳到主要内容
版本:Dev

单点登录(SAML)

单点登录(SSO)让 AISIX Enterprise 或 AISIX Cloud 组织的成员通过你的身份提供方(IdP)登录控制台,而不必使用密码。每个组织配置自己的 SAML 2.0 连接,因此可以对接 Microsoft Entra ID、Okta、Keycloak 或其他任何标准 SAML 身份提供方。本页介绍适用于所有身份提供方的配置和行为。使用 Microsoft Entra ID 的分步配置请参见集成 Microsoft Entra ID。

AISIX Enterprise 和 AISIX Cloud 的所有套餐都提供 SSO。SSO 在控制台 设置 页面的 身份认证 标签页中,通过 单点登录(SAML) 卡片配置。

一个连接可以:

  • 让现有成员通过身份提供方登录;
  • 在新成员首次登录时将其加入组织(JIT 预配);
  • 根据身份提供方发送的属性设置成员角色;
  • 要求所有者以外的成员必须通过 SSO 访问组织。

SSO 与 SCIM 目录同步互为补充:SCIM 预先创建、更新和停用成员,SSO 负责这些成员如何登录。两者也可以单独使用。

控制面账号属于个人而不属于组织:同一个账号可以是多个组织的成员。因此,只有当账号已与此人在身份提供方中的身份关联后,SSO 才会登录到该账号。在 AISIX Enterprise 中,首次登录时按邮箱地址建立关联。在 AISIX Cloud 中,由本人在关联页面确认,除非邮箱地址位于组织的某个已验证域名内。参见登录如何找到账号。

谁可以配置 SSO​

只有组织 所有者 可以创建、修改或移除 SSO 连接。管理员只能只读查看该卡片,其他角色(包括自定义角色)看不到它。

这样设计是有意为之:掌控组织所信任的身份提供方的人,可以以组织内任意成员(包括所有者)的身份登录。因此选择哪个身份提供方,是所有者才能做的决定。

服务提供方信息​

单点登录(SAML) 卡片顶部列出需要在身份提供方中登记的信息。这些值由控制面的公开 URL 和组织 ID 生成:

字段格式Entra ID 字段
实体 ID(标识符)<public-base-url>/api/auth/sso/saml/<org-id>/metadataIdentifier (Entity ID)
断言消费服务 URL(回复 URL)<public-base-url>/api/auth/sso/saml/<org-id>/acsReply URL (Assertion Consumer Service URL)
登录 URL<public-base-url>/login?sso=<org-slug>Sign on URL

实体 ID 同时也是服务提供方元数据文档的 URL。该文档是公开的,支持导入 SP 元数据的身份提供方可以直接读取;下载服务提供商元数据 保存的也是同一份文档。元数据声明了一个 HTTP-POST 断言消费服务、不签名的认证请求,以及要求签名的断言。

实体 ID 和回复 URL 使用组织 ID 而不是组织 slug,因此即使 slug 改变,身份提供方中的登记也仍然有效。登录 URL 使用 slug。

在 AISIX Enterprise 中,<public-base-url> 即 AISIX_CLOUD_PUBLIC_BASE_URL 的值,在 Helm Chart 中为 api.publicBaseURL。它必须是浏览器访问控制面实际使用的 URL,因为身份提供方会把浏览器送回这个地址。参见运行时 URL。

配置身份提供方​

对于 Microsoft Entra ID,请按照分步指南集成 Microsoft Entra ID 操作。对于其他 SAML 2.0 身份提供方,配置包含相同的几个部分:

  1. 在身份提供方中登记控制面。 创建一个 SAML 应用,填入 SSO 卡片中的实体 ID、断言消费服务 URL,以及登录 URL(如果身份提供方有对应字段)。支持导入服务提供方元数据的身份提供方,也可以直接从实体 ID URL 读取。
  2. 发送稳定的名称标识符。 控制面按断言中的名称标识符(NameID)识别再次登录的人,因此 NameID 必须是稳定的个人标识,不随邮箱地址或用户名变化,例如不可变的用户 ID。对于 Microsoft Entra ID,请使用 user.objectid,格式为 Persistent。transient 格式的 NameID 每次登录都会变化,会被拒绝并返回 SSO_NAME_ID_TRANSIENT;没有 NameID 的断言会被拒绝并返回 SSO_NAME_ID_MISSING。请在成员开始登录之前确定 NameID,参见之后更改 NameID。
  3. 发送邮箱地址。 在 邮箱属性 指定的属性中发送每个人的邮箱地址。同时发送显示名称;如果使用角色映射规则,还要发送规则读取的属性。
  4. 签名,不加密。 身份提供方必须对响应或断言签名,且不能加密断言。
  5. 授予访问权限。 如果身份提供方要求,把需要登录的人员分配到该应用。
  6. 将身份提供方元数据导入控制面。 在 SSO 卡片上,将身份提供方的元数据粘贴到 身份提供商元数据 XML 中并选择 读取元数据,或选择 上传元数据文件。检查 身份提供商实体 ID、单点登录 URL 和 签名证书,然后开启 启用单点登录,按照连接设置选择其他选项,再选择 保存。

控制面从元数据中读取身份提供方的实体 ID、HTTP-Redirect 登录端点和签名证书。它不会从 URL 下载元数据,因此请粘贴或上传元数据文档本身。也可以不用元数据,手动填写这三个字段。

然后通过登录 URL 登录以测试连接。

轮换签名证书​

一个连接最多保存 10 个签名证书,由其中任一证书签名的响应都会被接受。每个证书可以以 PEM 格式粘贴,也可以以 base64 编码的 DER 格式(即元数据文档和身份提供方控制台显示的格式)粘贴。

轮换证书前,请记录是否已开启 强制单点登录,因为修改证书列表会将其关闭。

在旧证书仍有效时,按以下顺序轮换身份提供方的证书,以避免登录中断:

  1. 在身份提供方中创建新证书,但暂不用它签名。
  2. 在 SSO 卡片中选择 添加证书,粘贴新证书后保存。
  3. 让身份提供方改用新证书签名。
  4. 确认使用新证书可以正常登录后,从 SSO 卡片中移除旧证书并保存。
  5. 如果轮换前已开启强制单点登录,请重新开启它。

添加或移除证书都会自动关闭 强制单点登录。只有在新证书验证可用后,才恢复之前的强制设置。如果身份提供方使用 SSO 卡片中没有的证书签名,所有登录都会以 SSO_RESPONSE_INVALID 失败。Entra ID 中的具体步骤参见 Entra ID 指南中的轮换签名证书。

连接设置​

设置默认值说明
启用单点登录关闭成员可以通过身份提供方登录。配置过程中可以先保存一个未启用的连接。
登录时自动添加新成员(JIT)关闭组织尚不认识的人首次登录时自动成为成员。参见成员如何加入。
默认角色member登录时新加入成员的角色;存在角色映射规则但没有规则命中时,也使用该角色。可以是 member、admin 或自定义角色,不能是 owner。
邮箱属性http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress携带邮箱地址的断言属性。留空使用默认值。
显示名称属性http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name携带显示名称的断言属性。留空使用默认值。
身份提供商实体 ID、单点登录 URL、签名证书无连接所信任的身份提供方,通常从其元数据中填写。单点登录 URL 是身份提供方的 HTTP-Redirect 端点。
角色映射无规则按顺序根据身份提供方属性设置成员角色的规则。参见将身份提供方属性映射为角色。
强制单点登录关闭所有者以外的成员只能通过 SSO 访问组织。参见强制单点登录。

属性按 Name 或 FriendlyName 匹配,不区分大小写。断言中缺少邮箱属性时,如果 NameID 是邮箱格式,就把它用作邮箱地址;否则断言中没有邮箱地址。这样的登录对身份已关联账号的人照常有效,首次登录则进入关联页面。缺少显示名称属性时,使用名和姓拼接;名和姓也没有时,使用邮箱地址;没有邮箱地址时,使用 NameID。

移除连接 会删除该连接。成员将无法再通过身份提供方登录,已通过它打开的会话会持续到过期为止。

配置变更会以资源类型 sso_connection 记录在审计日志中;SSO 添加成员或修改成员角色时,会记录为 member 变更。身份与账号之间的关联也会被记录,参见身份关联。

通过 SSO 登录​

登录页面提供的 SSO 入口取决于部署方式:

  • AISIX Enterprise。 登录页面从不要求输入组织标识。当组织有已启用的 SSO 连接时,页面会显示以组织名称命名的 使用 <组织> 的 SSO 登录 按钮,点击后直接跳转到身份提供方。没有已启用的连接时,页面上完全没有 SSO 入口。
  • AISIX Cloud。 成员选择 使用 SSO 登录,输入组织标识(即登录 URL 末尾的 slug),随后被带到身份提供方。

在身份提供方登录后,成员即进入该组织;如果其身份尚未关联账号,首次登录会进入关联页面。两种产品中,登录页面都会保留密码登录表单,即使开启了强制单点登录也是如此,因为所有者始终可以使用密码登录。

登录 URL /login?sso=<org-slug> 在两种产品中都可用,它打开的页面只有该组织的 使用 SSO 登录 按钮。可以把它分享给成员,或在身份提供方中登记为登录 URL,使身份提供方的应用启动入口(例如 Entra ID 的 My Apps 磁贴)指向该页面。成员随后在该页面上选择 使用 SSO 登录。

从 1.5.x 或更早版本升级、仍包含多个组织的 AISIX Enterprise 控制面,在这些组织合并为一个之前不会显示 SSO 按钮。

登录必须在发起它的浏览器中、在 10 分钟内完成。找到此人账号的登录会替换该浏览器原有的会话;进入关联页面的登录则保留浏览器原有的会话。

以下功能不受支持:

  • 身份提供方发起的登录。 控制面会拒绝不对应其自身发起登录的 SAML 响应。
  • 单点登出。 退出控制台只结束控制台会话,身份提供方的会话仍然保留。
  • 加密断言。 身份提供方必须对响应或断言签名,且不能加密断言。

登录如何找到账号​

某个身份首次登录时,控制面会把该连接及该身份的 NameID 关联到一个账号。之后的每次登录都只通过这个关联找到账号,不再参考断言中的邮箱地址,因此即使此人在身份提供方中的邮箱地址发生变化,仍会登录到同一个账号。一个连接中,每个 NameID 只关联一个账号,每个账号也只关联一个 NameID。

以下情况会删除关联:

  • 此人被移出组织,无论是在控制台中、通过 SCIM,还是其他任何方式;
  • 连接被移除;
  • 身份提供商实体 ID 发生变化,这会删除该连接的所有关联。

修改身份提供方的单点登录 URL 或证书不会影响关联。

关联以资源类型 sso_identity_link 记录在审计日志中:建立关联时记录 create,via 为 connect、trusted_email 或 email_claim;因账号已关联另一个 NameID 而拒绝关联时记录 reject;因已验证域名接管未验证账号而删除关联时记录 delete。接管本身以资源类型 verified_domain_claim 记录,参见审计记录。关联页面发出的邮箱验证链接以资源类型 sso_email_claim 记录:发送链接时记录 create,使用链接时记录 complete。审计记录中从不包含任何 Token。

首次登录​

还没有关联时,结果取决于控制面是否信任身份提供方断言的邮箱地址:

  • 在 AISIX Enterprise 中,身份提供方由运维方自己掌控,信任所有地址。
  • 在 AISIX Cloud 中,每个组织都掌控自己的身份提供方,它可以断言任何人的地址。只有组织已验证域名内的地址才被信任,按域名精确匹配,不包括子域名。

地址受信任时,登录会关联使用该地址的账号(不区分大小写)。没有账号使用该地址时,只有在组织会接纳此人(已开启 JIT 预配,或此人有待接受的邀请)时,才会创建一个没有密码的账号;否则登录被拒绝并返回 SSO_NOT_A_MEMBER,也不会创建账号。此人直接进入组织,不经过关联页面。

在 AISIX Cloud 中,使用受信任地址却从未验证过邮箱的账号,是由没有证明自己拥有该地址的人注册的。登录会接管这个账号:账号失去密码、会话、尚未使用的邮箱验证链接,以及与其他组织 SSO 连接的关联。账号名称改为断言中的显示名称,即 JIT 预配新建账号时会使用的名称;账号对《用户协议》和《隐私政策》的同意记录被清除,邮箱地址被标记为已验证。接管会记录为一条 verified_domain_claim 审计记录,参见组织域名。已验证过邮箱的账号会直接关联,不会被接管,并保留原名称。在 AISIX Enterprise 中不会接管任何账号:账号保留名称、密码和会话。

其他情况,即 AISIX Cloud 中已验证域名以外的地址,以及两种产品中没有邮箱地址的断言,此人会进入关联页面。

关联页面​

关联页面 /sso-connect 会说明此人已通过组织的 SSO 以哪个邮箱地址完成认证,但该身份尚未关联任何账号。该身份在完成登录的浏览器中等待 10 分钟。在本人确认之前,不会建立任何关联。页面提供以下几种方式:

  • 登录已有账号。 使用任意账号的密码登录,然后确认关联。浏览器已登录时,页面会针对当前账号提供 关联到 <email>,以及 使用其他账号。在 AISIX Cloud 中,与所有密码登录一样,账号的邮箱地址必须已经验证。
  • 创建新账号。 邮箱地址固定为身份提供方发送的地址,不能修改。此人像AISIX Cloud 新注册账号一样验证该地址。从验证链接登录后,浏览器会回到该组织的 SSO 登录页面,此人再次通过 SSO 登录并确认关联。断言中没有邮箱地址、该地址属于没有密码的账号,或部署只允许通过邀请创建账号(AISIX Enterprise 即是如此)时,不提供此选项。
  • 发送验证链接。 如果断言中的邮箱地址属于一个没有密码的现有账号(例如通过 SCIM 预配的账号,或在 AISIX Enterprise 中由管理员创建的账号),页面会提供 向 <email> 发送验证链接,而不是创建新账号。链接一小时内有效,只能使用一次,发出新链接后旧链接失效。链接不依赖浏览器,可以在任何地方打开。打开后的页面会写明组织的名称和标识以及账号,选择 关联并登录 即关联该身份、把邮箱地址标记为已验证并登录。之后账号仍然没有密码。如果浏览器当前登录的是另一个账号,页面会说明关联后将退出该账号。

有密码的账号只能通过登录来关联。

警告

关联账号后,该组织的身份提供方可以直接以该账号登录,无需密码。它打开的会话是该账号的普通会话,可以访问该账号所属的每一个组织,强制要求各自单点登录的组织除外。只关联你愿意交由这个身份提供方控制的账号。

仍需修改密码的会话不能关联,请求会被拒绝并返回 PASSWORD_CHANGE_REQUIRED。请先修改密码。

之后更改 NameID​

连接从不替换已有的关联。当身份提供方开始为某人发送不同的 NameID 时(例如你修改了身份提供方的 NameID 来源,或 NameID 是一个已被改名的用户名),此人会被拒绝并返回 SSO_ACCOUNT_ALREADY_LINKED。要让此人重新登录,请将其移出组织(关联随之删除),再重新加入。

自动替换关联是不安全的:如果身份提供方允许用户自行修改邮箱地址,替换就可能把一个已关联的账号交给其他人。

成员如何加入​

确定账号后,由组织决定是否接纳:

  • 此人已是组织成员(无论是受邀加入、在控制台中创建,还是通过 SCIM 预配):直接登录。通过 SCIM 预配的成员仍由 SCIM 管理。
  • 此人是等待加入的 SCIM 成员,且 NameID 等于目录发送的 externalId:关联该身份即激活该成员。参见等待加入的成员。
  • 此人有待接受的组织邀请,且邀请发往账号已验证的邮箱地址,或身份提供方发送的受信任地址:邀请被接受,此人以邀请中的角色加入,除非角色映射规则给出了其他角色。
  • 以上都不是,且已开启 JIT 预配:此人以默认角色或规则给出的角色加入。已有账号(例如属于其他组织的账号)会被加入本组织。
  • 以上都不是,且未开启 JIT 预配:登录被拒绝并返回 SSO_NOT_A_MEMBER,也不会建立关联。请邀请此人,或通过 SCIM 预配。

成员资格已被停用(例如被 SCIM 停用)的成员无法登录,登录会被拒绝并返回 SSO_MEMBER_DEACTIVATED。

SSO 创建的账号没有密码。在 AISIX Enterprise 中,管理员仍可以为其启用密码登录。

将身份提供方属性映射为角色​

角色映射规则根据 SAML 断言中的属性设置成员角色。一个连接最多 50 条规则,每条规则包含 属性、运算符、值 和 角色:

运算符控制台标签命中条件
exact_match等于(第一个值)属性的第一个值等于该值。
contains_string包含(第一个值)属性的第一个值包含该值。
exact_match_in_array任一值等于属性的任一值等于该值。
contains_string_in_array任一值包含属性的任一值包含该值。

属性名按 Name 或 FriendlyName 匹配,不区分大小写;值按原样比较,区分大小写。规则按顺序检查,第一条命中的规则生效。

规则的作用:

  • 有规则时,每次登录都会把成员角色设为第一条命中规则的角色;没有规则命中时设为默认角色。这同样会覆盖成员通过 SSO 登录接受的邀请中的角色,以及在控制台中手动修改的角色(在成员下次登录时)。
  • 没有规则时,SSO 只在此人加入时设置角色(邀请中的角色或默认角色),之后不再修改。
  • 所有者永远不会被修改,无论是否有规则。

如果组织同时使用 SCIM,SSO 写入的角色优先:SCIM 的组到角色映射不再修改该成员的角色。删除所有规则、移除连接,或在控制台中手动修改该成员的角色,都会把这些角色交还给 SCIM 管理。

被默认角色或某条规则引用的自定义角色,在连接仍使用它时无法删除。

对于 Microsoft Entra ID,指南介绍了如何定义应用角色并将其映射为组织角色。

强制单点登录​

强制单点登录 使 SSO 成为所有者以外的成员访问组织的唯一方式。只有已启用的连接才能开启此项。

开启后:

  • 所有者以外的成员只能使用最近 24 小时内完成过本组织 SSO 的会话访问组织,即通过本组织 SSO 登录,或在关联页面确认关联。24 小时从那次登录算起,使用会话不会延长。其他组织的 SSO 不算数。否则,控制台会把他们带到 需要单点登录 页面 /sso-required?org=<org-slug>,该页面提供 SSO 登录入口;API 调用返回 403,错误码为 SSO_REQUIRED。该组织仍会出现在其组织列表中,便于找到。
  • 所有者不受限制,始终可以用密码登录(开启了双因素认证时还需输入验证码),从而在身份提供方故障或配置错误时保留进入组织的途径。
  • 已有的 Admin Token 继续有效。

无论是否开启强制单点登录,同样在 24 小时内完成过本组织 SSO 的会话也满足本组织的密码有效期和双因素认证要求,因为它们由身份提供方负责。

修改身份提供方实体 ID、单点登录 URL 或证书(包括添加证书)会自动关闭强制单点登录,因为新的身份提供方设置还没有经过登录验证。请先通过身份提供方成功登录一次,再重新开启。

SSO 会话​

SSO 打开的会话是该账号的普通会话,与密码会话相同:

  • 可以访问该账号所属的每一个组织,但须满足各组织的强制单点登录设置。
  • 有效期 7 天,使用期间会自动延长。
  • 与其他会话一样,可以修改账号的个人资料和接受邀请。
  • 在 AISIX Cloud 中可以创建组织;AISIX Enterprise 不允许创建组织。

修改密码要求账号原本就有密码,且成员须提供该密码。通过 SSO 即时预配创建的账号没有密码,因此无法设置密码。在 账号设置 页面上,它的 密码 卡片显示一条说明,而不是修改密码的表单。

如果浏览器原本已以同一个人的身份登录,新会话会保留原会话完成过的 SSO 登录记录,因此通过一个组织的 SSO 登录不会让另一个组织已有的 SSO 登录记录失效。

故障排查​

SSO 登录未完成时,浏览器会回到 /login?sso=<org-slug>&sso_error=<CODE>,页面会说明错误原因。在 AISIX Enterprise 中,cp-api 也会在日志中记录拒绝 SAML 响应的原因。

错误码可能原因解决方法
SSO_NOT_ENABLED没有使用该标识的组织,或其 SSO 连接未启用。登录过程中连接被停用或被替换时也会返回该错误。检查组织标识,并确认已开启 启用单点登录。
SSO_UNSOLICITED_RESPONSE响应不对应任何进行中的登录:身份提供方自行发起了登录、登录已超过 10 分钟,或响应已被使用过。从控制台登录页面发起登录。在身份提供方中登记登录 URL(例如 Entra ID 的 Sign on URL),使其应用启动入口打开控制台登录页面。
SSO_RESPONSE_INVALID响应未通过验证:可能由连接中不存在的证书签名、来自其他颁发者、指向其他受众或接收方,或不在有效期内。将 身份提供商实体 ID 和证书与身份提供方核对,将在身份提供方中登记的实体 ID 和回复 URL 与 SSO 卡片核对,并检查身份提供方和控制面的时钟。
SSO_ENCRYPTED_ASSERTION_UNSUPPORTED身份提供方加密了断言。在身份提供方中关闭该应用的 Token 或断言加密。
SSO_IDP_ERROR身份提供方返回了失败状态。在身份提供方的登录日志中查看原因。
SSO_NAME_ID_MISSING断言中没有 NameID。配置身份提供方为每个用户发送 NameID。
SSO_NAME_ID_TRANSIENTNameID 为 transient 格式,只在一次登录中标识此人。发送 persistent 格式的 NameID,或其他对同一个人保持不变的格式,例如不可变的用户 ID。使用 Entra ID 时,使用 user.objectid,格式为 Persistent。
SSO_BROWSER_MISMATCH登录在发起它的浏览器以外完成、耗时超过 10 分钟,或浏览器拦截了登录 Cookie。在同一个浏览器中从登录页面重新发起登录。
SSO_NOT_A_MEMBER此人不是成员,没有待接受的邀请,且未开启 JIT 预配。邀请此人、通过 SCIM 预配,或开启 登录时自动添加新成员(JIT)。
SSO_MEMBER_DEACTIVATED成员资格已被停用。重新激活该成员,例如由 SCIM 管理时在身份提供方中重新激活。
SSO_ACCOUNT_ALREADY_LINKED该账号在此连接中已关联另一个 NameID,通常是因为身份提供方为此人发送的 NameID 变了。将此人移出组织再重新加入。参见之后更改 NameID。
SSO_IDENTITY_ALREADY_LINKED在关联页面上:该身份已在此期间关联到另一个账号。再次通过 SSO 登录,即会登录到那个账号。
SSO_CONNECT_EXPIRED在关联页面上:浏览器中没有等待关联的身份。它已经关联,或已超过 10 分钟。再次通过 SSO 登录。
SSO_CLAIM_LINK_INVALID关联页面发出的验证链接无效、已过期、已使用,或已被更新的链接取代。再次通过 SSO 登录并发送新链接。
INTERNAL_ERROR控制面处理登录时出错。重试。在 AISIX Enterprise 中,检查 cp-api 日志。

如果身份提供方自身报告回复 URL 不匹配(例如 Entra ID 的 AADSTS50011),或者所有响应都以 SSO_RESPONSE_INVALID 失败,请先检查公开 URL。SSO 卡片用它生成实体 ID 和回复 URL,因此如果该值浏览器无法访问,或在登记应用后发生了变化,所有登录都会失败。请修正 AISIX_CLOUD_PUBLIC_BASE_URL 或 api.publicBaseURL,再把 SSO 卡片中的新值复制到身份提供方。

Entra ID 在其自身页面上显示的错误(例如用户未分配到应用时的 AADSTS50105),参见 Entra ID 指南的故障排查。

下一步​

使用 SCIM 目录同步从同一个身份提供方预配和取消预配成员,使用角色与自定义角色定义 SSO 分配的角色。使用密码登录的成员,参见密码策略与双因素认证。