一条石砌通道上,前后两道门相互连通。

产品笔记

退出登录的传递

用户只登录一次,背后却可能创建多个会话。退出登录时,需要明确哪些会话应当结束,以及退出应当传递到哪里。

登录一次,产生三把钥匙

假设服务接入了“使用Google登录”。对用户而言,只是点击了一次按钮。

但在内部,路径上的每个系统都会创建并保存自己的会话。Google一份,Authrim一份,自家应用一份,共三份。

只要某处的会话仍然有效,用户就可能继续操作,或不输入密码就再次登录。

退出登录不只是显示“已退出”。
需要先确定退出的范围,再结束该范围内的会话。

令牌撤销是另一件事

这里的“钥匙”指会话。访问令牌和刷新令牌采用不同的机制,结束会话并不一定会使已签发的令牌失效。撤销令牌需要另行处理。

在OIDC中,会话退出、令牌撤销、上游账户停用是三种不同操作。本文只讨论会话。令牌何时失效,请参阅令牌内省与撤销

Authrim位于中间

在这条连接中,上游身份提供商提供登录,应用请求登录。Authrim面向不同方向时,承担的角色也会变化。

上游IdP Google、Entra ID、Apple Authrim 你的身份平台 自家应用 用户实际使用的界面 请求登录 =请求方(RP) 提供登录 =提供方(OP) 方向不同 角色不同
这就像旅行社:对旅客,它安排旅行;对航空公司,它是购买座位的客户。Authrim也同时承担两种角色

退出通知常常停在半途

登录沿着路径完成,而退出必须有人主动传递

结束上游会话,不会自动删除Authrim和应用中的会话。需要把结束请求传到下游,再由各接收方结束对应会话。下图展示的是所需通知方式和配置均已就绪时的链路。

链路中断 上游IdP 会话已结束 通知未送达 Authrim 会话仍有效 自家应用 会话仍有效 结果:仍可能访问 链路连通 上游IdP 会话已结束 “结束此会话” 签名通知 Authrim 结束会话并向下游转发 “结束此会话” 签名通知 自家应用 结束会话 结果:三份会话均结束
区别在中间的箭头:Authrim能否接收通知,并继续发送给下游?上游提供商和各应用也必须支持并配置所需方式,链路才能成立。

在实际工作中会怎样表现

场景传递中断的后果
离职处理 人事部门撤销访问权限后,笔记本上的应用仍然打开,内部数据直到第二天早上仍可见。
共享终端 在零售、医院或呼叫中心,前一位用户已退出登录,另一个标签页却仍显示其控制台。
设备丢失 点击了‘退出所有设备’,实际却只结束了当前会话。
事件响应 封禁了受入侵的账户,攻击者的会话却仍持续到过期。
审计 ‘请证明退出登录会传递到所有系统。’却拿不出证据。

不是没有退出按钮,界面也确实发生变化。问题在于生效范围比预想的小,因此不容易发现。

经浏览器传递的局限

通知下游主要有两种方式,其中依赖浏览器的方式会遇到更多限制。

经浏览器传递 Authrim 浏览器 每个应用对应隐藏框架 自家应用 浏览器隐私保护可能阻止通知 服务器直接通信 Authrim 直接发送签名通知 不经过浏览器 自家应用
上方通过不可见框架通知应用,可能受到浏览器隐私保护限制。下方的后通道直接连接服务器,不依赖浏览器状态。但这不代表一定送达:网络故障、接收方停机、超时和5xx响应都可能造成失败。重试、队列和失败记录需要由实现提供。

Authrim的认证覆盖接收后通道通知的能力。接收和向下游发送需要分别验证。

同时验证接收方与发送方

Authrim对上游是依赖方(RP),对应用是OpenID提供方(OP)。要继续传递退出通知,两种角色都必须遵循规范。

  • 作为RP:验证上游通知,并结束对应的Authrim会话。
  • 作为OP:向关联应用发送通知,让应用结束对应会话。

OP和RP的退出登录协议配置(profile)认证,为这两种角色提供验证依据。这里的profile指一组特定的协议要求,而不是配置文件。Authrim通过OpenID Foundation的自我认证流程,使用官方一致性测试,取得了两侧的退出登录协议配置认证。

认证表示提交版本通过了所申请协议配置的一致性测试。它不保证客户网络及所有关联应用中的会话都会立即结束。

上游和各应用必须支持所需方式,并配置通知端点与会话对应关系。停用上游账户不一定会触发退出通知。还应在实际部署中验证通知失败、重试及失败可见性。

认证版本和协议配置见OpenID Foundation的Certified OpenID Relying Parties & Logout Profiles列表。认证范围见认证制度说明

退出之后,哪里还保留着登录状态?

交接共享终端或终止离职员工访问时,需要确认的就是这个范围。Authrim接收并转发通知,连接上游与应用的会话结束处理。认证是实现的验证依据,而关联环境中的测试用于确认实际生效范围。