跳到主要内容
版本:1.6.0

单点登录(SAML)

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

SaaS 服务和 On-Premises 部署都提供 SSO,且不受套餐限制。SSO 在控制台的 设置 页面中,通过 单点登录(SAML) 卡片配置。

一个连接可以:

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

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

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

谁可以配置 SSO​

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

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

服务提供方信息​

单点登录(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。

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

配置身份提供方​

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

  1. 在身份提供方中登记 AISIX Cloud。 创建一个 SAML 应用,填入 SSO 卡片中的实体 ID、断言消费服务 URL,以及登录 URL(如果身份提供方有对应字段)。支持导入服务提供方元数据的身份提供方,也可以直接从实体 ID URL 读取。
  2. 发送稳定的名称标识符。 AISIX Cloud 按断言中的名称标识符(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. 将身份提供方元数据导入 AISIX Cloud。 在 SSO 卡片上,将身份提供方的元数据粘贴到 身份提供商元数据 XML 中并选择 读取元数据,或选择 上传元数据文件。检查 身份提供商实体 ID、单点登录 URL 和 签名证书,然后开启 启用单点登录,按照连接设置选择其他选项,再选择 保存。

AISIX Cloud 从元数据中读取身份提供方的实体 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 端点。
角色映射无规则按顺序根据身份提供方属性设置成员角色的规则。参见将身份提供方属性映射为角色。
强制单点登录关闭Owner 以外的成员只能通过 SSO 访问组织。参见强制单点登录。

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

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

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

通过 SSO 登录​

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

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

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

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

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

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

以下功能不受支持:

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

登录如何找到账号​

某个身份首次登录时,AISIX Cloud 会把该连接及该身份的 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。审计记录中从不包含任何令牌。

首次登录​

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

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

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

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

其他情况,即 SaaS 服务上已验证域名以外的地址,以及两种部署方式下没有邮箱地址的断言,此人会进入关联页面。

关联页面​

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

  • 登录已有账号。 使用任意账号的密码登录,然后确认关联。浏览器已登录时,页面会针对当前账号提供 关联到 <email>,以及 使用其他账号。在 SaaS 服务上,与所有密码登录一样,账号的邮箱地址必须已经验证。
  • 创建新账号。 邮箱地址固定为身份提供方发送的地址,不能修改。此人像新注册账号一样验证该地址。从验证链接登录后,浏览器会回到该组织的 SSO 登录页面,此人再次通过 SSO 登录并确认关联。断言中没有邮箱地址、该地址属于没有密码的账号,或部署只允许通过邀请创建账号(On-Premises 控制面即是如此)时,不提供此选项。
  • 发送验证链接。 如果断言中的邮箱地址属于一个没有密码的现有账号(例如通过 SCIM 预配的账号,或在 On-Premises 控制面上由管理员创建的账号),页面会提供 向 <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 创建的账号没有密码。在 On-Premises 控制面上,管理员仍可以为其启用密码登录。

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

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

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

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

规则的作用:

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

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

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

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

强制单点登录​

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

开启后:

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

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

SSO 会话​

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

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

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

故障排查​

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

错误码可能原因解决方法
SSO_NOT_ENABLED没有使用该标识的组织,或其 SSO 连接未启用。登录过程中连接被停用或被替换时也会返回该错误。检查组织标识,并确认已开启 启用单点登录。
SSO_UNSOLICITED_RESPONSE响应不对应任何进行中的登录:身份提供方自行发起了登录、登录已超过 10 分钟,或响应已被使用过。从 AISIX Cloud 登录页面发起登录。在身份提供方中登记登录 URL(例如 Entra ID 的 Sign on URL),使其应用启动入口打开 AISIX Cloud 登录页面。
SSO_RESPONSE_INVALID响应未通过验证:可能由连接中不存在的证书签名、来自其他颁发者、指向其他受众或接收方,或不在有效期内。将 身份提供商实体 ID 和证书与身份提供方核对,将在身份提供方中登记的实体 ID 和回复 URL 与 SSO 卡片核对,并检查身份提供方和控制面的时钟。
SSO_ENCRYPTED_ASSERTION_UNSUPPORTED身份提供方加密了断言。在身份提供方中关闭该应用的令牌或断言加密。
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控制面处理登录时出错。重试。在 On-Premises 控制面上,检查 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 分配的角色。