跳到主要内容

单点登录

用户可以通过所在组织自己的身份提供商(Microsoft Entra ID、Okta、Google Workspace,或任何 OpenID Connect 提供商)登录 DeviceChain,而不必使用 DeviceChain 密码。管理员只需连接一次提供商;之后它所代表的用户用已有的账号登录,由提供商而不是 DeviceChain 来判定他们是谁,以及账号是否仍然有效。

本页说明该功能的行为和限制。如需配置,请参阅配置单点登录。

状态

单点登录使用 OpenID Connect,不支持 SAML。Microsoft Entra ID、Okta 和 Google Workspace 的配置方案依据各提供商文档记载的行为编写,但尚未针对这些提供商的真实租户测试;整个流程已针对一个替身 OpenID Connect 提供商完成端到端测试。

连接​

**连接(connection)**是在实例上注册的一个身份提供商。只有超级用户可以通过控制台的 **Admin → Identity providers(管理 → 身份提供商)**或管理 API 创建、修改和删除连接。连接分为两种:

租户连接实例连接
提供商属于谁客户或组织自己的人员运营方自己的员工
服务对象你选定的一个或多个租户不属于任何租户:用于让运营人员登录实例
首次登录时创建身份是,前提是开启预配从不
如何对应到某个身份在链接请求获批后按邮箱匹配,或通过预配只能由超级用户显式建立链接
能否对应到持有系统角色的身份绝不能能:这正是它的用途
进入租户的方式只能进入它所服务的租户只能以超级用户身份进入,并记录在审计日志中

租户连接在结构上就无法让任何人以运营人员身份登录。无论提供商声明了什么,它产生的会话都不带系统角色,也没有管理权限;如果某次登录对应到持有系统角色的身份,则会被拒绝。实例连接必须要求多因素方法(requiredAmr,例如 mfa),或带有你记录的声明(mfaEnforcedByIdp),表明提供商强制执行多因素认证。预置的超级用户密码仍作为应急(break-glass)入口保留。

连接创建时处于禁用状态。只有在有人批准其发现快照并启用之后,它才可使用。

已验证域名​

一个连接代表一组邮箱域名,每个域名由超级用户断言并记录其姓名。当用户在控制台登录页输入邮箱时,由域名的精确匹配选定连接。一个域名只属于一个连接,DeviceChain 拒绝公共后缀(com、co.uk)和知名的个人邮箱域名(gmail.com、outlook.com 等),因为为这些域名做断言会把陌生人路由到你的提供商。

对于尚未链接到任何身份的首次登录,只有在提供商为该地址担保(email_verified;对 Microsoft Entra ID 则是 xms_edov 声明),并且该地址属于连接的某个域名时,才会被接受。没有任何设置可以让系统信任提供商未验证的地址。

共享的多租户颁发者会被拒绝,除非连接已固定到你的组织:

  • Microsoft 颁发者必须指定一个租户 ID,且连接必须要求声明 tid 等于该 ID。common、organizations 和 consumers 会被直接拒绝。
  • Google 连接必须要求声明 hd(你的 Workspace 域名),并且令牌中的 hd 必须与地址的域名一致。否则任何 Google 账号(包括个人账号)都可以登录。

批准发现文档​

创建连接时,DeviceChain 会获取提供商的发现文档,并保留其端点(授权、令牌、签名密钥、退出登录)的快照。超级用户审阅快照,并凭其指纹批准(Approve endpoints)。登录只使用已批准的端点,从不实时获取发现文档。如果提供商之后迁移了某个端点,Refresh from provider 会替换快照并撤销批准,连接会拒绝登录,直到有人批准新的快照。登录时只会获取签名密钥集的内容,因为密钥轮换是常规操作。

对提供商的每个请求都经过平台的出口防护,因此位于私有、环回或链路本地地址的提供商会被拒绝,除非运营方允许了其地址范围(参见配置单点登录)。

登录​

控制台和仪表盘应用在密码表单旁显示 Sign in with SSO。流程是带 PKCE 的 OpenID Connect 授权码流程:

  1. 用户输入邮箱并选择 Sign in with SSO。浏览器保留一个随机密钥,并发送其哈希。
  2. DeviceChain 记录该次登录(有效期十分钟,只能使用一次),并将浏览器重定向到提供商。
  3. 提供商对用户进行认证,然后返回 <issuerUrl>/sso/callback/<connection>。
  4. DeviceChain 检查应答:state 与连接是否匹配,令牌的签名、颁发者、受众、有效期和 nonce,连接要求的声明和方法,以及下文的身份规则。
  5. 它向浏览器交付一个有效期一分钟、只能使用一次的代码。浏览器用第 1 步的密钥兑换该代码,因此只有发起登录的浏览器才能完成登录,并获得与密码登录相同类型的身份令牌。之后用户照常选择租户。

接收代码的页面(控制台为 /login/sso/complete,仪表板应用为 /dash/sso/complete)会立即把代码从地址栏中移除,并以 Referrer-Policy: no-referrer 提供,因此它加载的任何内容都无法携带该地址。登录完成后,或用户返回登录表单时,应用会重新加载,而不是继续停留在该页面上,因此会话的其余部分会发送正常的 Referer;默认的 OpenStreetMap 底图需要它。如果你自己的代理位于控制台之前,请把任何去除 Referer 的响应头限定在这两个确切路径上。

登录被拒绝时,用户只会看到笼统的提示(“Single sign-on did not allow this account in”、“your account is not linked yet”),不会知道是哪项检查未通过;确切的结果由指标 devicechain_usermanagement_sso_logins_total 计数,拒绝事件连同提供商断言的地址一起写入审计日志。

身份、链接与预配​

DeviceChain 绝不会因为邮箱地址看起来相似,就把外部账号链接到现有身份。链接有四种方式,每一种都会被审计:

  • 预配(即时,just-in-time)。在开启预配的租户连接上,如果登录的地址没有任何身份,就会创建一个(无密码)并链接。这是唯一的自动写入。
  • 超级用户批准链接请求。如果登录既未链接也未被预配(其地址已有身份,或该连接不做预配),登录会被拒绝,并在 Identity providers → Link requests 下出现一条链接请求。超级用户批准或拒绝它。如果该身份在连接所服务的租户中已有、且没有任何连接管理的成员关系,批准时需要做出选择:convert 表示此后由该连接管理这些成员关系,keep_manual 表示保持原样。标记为 subject changed 的请求表示该身份已在该连接上链接到另一个不同的账号,这正是邮箱地址被回收复用时的表现,请保持警惕。
  • 超级用户直接链接(管理 API 中的 linkIdentity、unlinkIdentity)。实例连接只能由超级用户链接:通过这种方式,或通过批准链接请求。
  • **用户链接自己的账号。**以密码登录后,用户可以发起 beginSsoLink;提供商必须报告该身份自己的邮箱地址。此功能可通过 API 使用,控制台暂时还没有对应按钮。

租户连接会拒绝持有任何系统角色的身份,即使链接是在授予该角色之前建立的。已链接到某个连接的身份,不能在同一连接上再绑定第二个账号。

身份上的邮箱地址绝不会根据提供商的声明更新。

组到角色的映射​

对于租户连接,每次登录都会重新计算用户在该连接所服务租户中的受管成员关系:连接的默认角色,加上令牌 groups 声明中出现的每个组所对应映射的角色。若没有任何角色,则禁用该受管成员关系;若成员关系缺失,则创建。管理员手动创建的成员关系不会被触碰,由其他连接管理的成员关系同样不会。

这些限制是有意设计的:

  • **仅限租户角色。**映射永远不能指定系统角色。拥有租户全部权限的映射或默认角色需要明确确认,并会被审计。
  • **在登录时生效。**提供商侧的变更会在用户下次登录时,或会话下次到达上限时(见下文)传达到 DeviceChain。
  • 组必须随令牌到达。如果连接映射了组,而提供商报告某人的组过多无法列出(Microsoft Entra ID 的“groups overage”),登录会被拒绝,而不是当作“没有组”处理,那样会禁用此人的访问权限。请在提供商处解决,只发送应用所需的组。groups 声明既不是字符串也不是字符串列表,或列出的组超过 1,000 个时,同样会被拒绝。
  • 删除连接只会禁用而不会删除它所管理的成员关系,因此提供商授予的角色绝不会悄悄变成手动授权。

为租户要求单点登录​

超级用户可以为租户设置 Require SSO(Admin → Tenants → 该租户,或 setTenantSsoEnforced)。此后:

  • 密码会话无法进入该租户。控制台会说明原因,并引导用户使用 Sign in with SSO;MCP 授权页面上的密码同样会被拒绝。
  • 已在该租户内的密码会话在下次刷新时结束。
  • 超级用户不受限制,并且他们的每次进入都会被审计,因此身份提供商故障绝不会把运营人员锁在门外。
  • **孤立租户拒绝。**开启它至少需要一个为该租户服务的已启用连接。反过来,你不能禁用或删除为要求单点登录的租户服务的最后一个已启用连接,也不能把该租户从中移除。DeviceChain 会拒绝,而不是悄悄重新放行密码。请先关闭该要求,或启用另一个为该租户服务的连接,再进行变更。

要求单点登录并不会移除任何人的密码。若要让个别用户只能使用 SSO,管理员使用 clearPassword;除非该身份已链接到一个它能够登录的已启用连接,否则该操作会被拒绝。

会话上限、退出登录与撤销​

每个连接都有一个会话上限:通过它登录一次最多可持续多久,从 DeviceChain 接受登录的时刻算起(而非提供商自己的认证时间),并且不会因刷新而延长。默认为 12 小时;范围是 15 分钟到 7 天,如果部署的刷新令牌有效期更短,上限也相应更低。到达上限后,会话在下次交换时结束,用户需要重新登录。该上限对已打开的会话同样生效。

  • 从控制台或仪表盘退出登录会在服务器上结束 DeviceChain 会话,但不会让用户退出身份提供商。
  • 撤销(管理 API 中的 revokeSessions;控制台暂时还没有对应按钮)会结束一个身份在所有设备上的所有登录,包括密码和 SSO,以及 MCP 授权。
  • 禁用或删除连接,或取消链接身份,会在下次交换时结束依赖它的会话。

残留窗口​

结束会话只是停止续期,无法收回已经签发的令牌。在退出登录、撤销、取消链接或禁用连接之后,已签发的访问令牌和身份令牌在过期前仍然有效:默认 15 分钟,管理 API 上同样如此。如果在提供商处取消某人的权限而 DeviceChain 没有任何操作,则只会在此人下次登录或会话上限结束会话时才传达到 DeviceChain,因此上界是会话上限(默认 12 小时)再加最多 15 分钟。此版本不支持 SCIM 预配,也不支持反向通道登出。如果该窗口对某类人群过长,请缩短连接的会话上限;人员紧急离职时使用 revokeSessions。

MCP 与 AI 智能体​

MCP 客户端使用的 OAuth 授权页面在密码表单旁提供 Sign in with SSO。用户在其提供商处登录,然后回到服务器保留的同一个授权请求,并看到同意页面:同意从不会被跳过,即使提供商是静默完成登录的。授权属于该次登录,并随之结束(会话上限,或一次撤销)。要求单点登录的租户会拒绝该页面的密码表单,因此仅使用 SSO 的组织同样可以连接 MCP 客户端。参见 AI 访问(MCP)。

公开地址(issuerUrl)​

登录流程的每一步都会回到本实例的公开地址,即 user-management 的 auth.issuerUrl。当实例通过 https 或在环回主机上提供服务时,chart 会从 ingress 推导出 <scheme>://<host>/api/user-management,显式设置的值始终优先。没有颁发者,就没有单点登录,也没有 OAuth 授权服务器:创建连接会失败,并提示 "sso requires a public issuer URL"。你在提供商处注册的重定向 URI 是 <issuerUrl>/sso/callback/<connection token>,在连接页面上显示为其 Callback address。

位于负载均衡器之后​

公开的登录发起入口按来源地址限流,该地址取 X-Forwarded-For 的最后一项;没有该标头时取连接的对端地址。如果你的负载均衡器或 ingress 把每个客户端的地址都替换成自己的地址(云负载均衡器在默认模式下会对流量做源地址转换),所有用户就会共享同一份配额:五次发起,之后每两秒一次,高峰期合法用户会被拒绝。请保留客户端地址:在 ingress 控制器的 Service 上设置 externalTrafficPolicy: Local,或使用负载均衡器的代理协议并让 ingress 配置为读取它。无论来源如何,全局限制和登录状态存储的上限都始终生效;存储写满时,发起登录会以失败关闭(参见配置单点登录中的 SsoStateStoreFull 告警),而密码登录不受影响。

审计内容​

审计日志记录:连接的创建、更新和删除,密钥变更,域名的添加和移除,发现文档的批准,链接和取消链接,链接批准,超级用户每次绕过租户的单点登录要求,实例连接的租户进入,以及每次拒绝及提供商断言的地址。原始令牌和代码绝不会被记录。

另请参阅​