### SSO 客户端登录/认证 单点登录(Single Sign-On, SSO)是一个通用术语,指的是允许用户通过单一的基于 Web 的认证门户登录应用程序的协议。例如 OpenID Connect、“中央认证服务”(CAS)以及 SAML。 本模块允许 Matrix 主服务器将用户认证委托给支持这些协议之一的外部认证服务器。在此过程中,涉及三个系统: - 一个使用本规范定义的 API 的 Matrix 客户端,它试图将用户认证至 Matrix 主服务器。 - 一个实现了本规范所定义 API 的 Matrix 主服务器,但其用户认证委托给了认证服务器。 - 一个“认证服务器”,负责对用户进行认证。 本规范只关注 Matrix 客户端与主服务器之间的通信,与用于与认证服务器通信的 SSO 协议无关。不同的 Matrix 主服务器实现可能支持不同的 SSO 协议。 实现 SSO 流程的客户端和主服务器需要同时考虑 [登录](#login) 和 [用户交互式认证](#user-interactive-authentication-api)。两个过程类似,但存在细微差异。 通常,SSO 系统要求在认证服务器上配置一个“回调”URI。用户完成认证后,浏览器会被重定向到该 URI。Matrix 主服务器的实现需提供合适的端点。例如,对于 CAS 认证,主服务器应为管理员提供配置 CAS 服务器及消费票据的 REST 端点的方法。 主服务器可以选择性地向用户显示多个可选的 SSO 选项,通常以多个“使用 $provider 登录”按钮的形式展示。这些被称为“身份提供者”(IdPs)。 #### 客户端通过 SSO 登录 流程概述如下: 1. Matrix 客户端调用 [`GET /login`](/client-server-api/#get_matrixclientv3login),以查询支持的登录类型,主服务器在响应中包含带有 `"type": "m.login.sso"` 的流程。 2. 为发起 `m.login.sso` 登录类型,Matrix 客户端引导用户浏览器跳转至用户主服务器上的 [`/login/sso/redirect`](/client-server-api/#get_matrixclientv3loginssoredirect) 端点。若用户选择了某个 `identity_providers`,则可能是该端点的 IdP 版本。 3. 主服务器以 HTTP 重定向响应至 SSO 用户界面,浏览器跟随重定向。 4. 认证服务器与主服务器交互,验证用户身份及其他认证信息,过程中可能涉及多次重定向。 5. 浏览器被引导至客户端提供的 `redirectUrl`,并带有 `loginToken` 查询参数,供客户端登录使用。 6. 客户端通过携带 `type` 为 `m.login.token` 的 [`/login`](/client-server-api/#post_matrixclientv3login) 端点调用,用登录令牌换取访问令牌。 对于原生应用,1 至 4 步通常通过打开嵌入式 Web 视图实现。 流程如下图所示: ``` Matrix 客户端 Matrix 主服务器 认证服务器 | | | |-------------(0) GET /login------->| | |<-------------登录类型--------------| | | | | | Webview | | | | | | |----->| | | | |--(1) GET /login/sso/redirect-->| | | |<---------(2) 302----------------| | | | | | | |<========(3) 认证流程==============>| | | | | | | |<--(4) 重定向到 redirectUrl--| | |<-----| | | | | | |---(5) POST /login (携 login token)->| | |<-------------访问令牌---------------| | ``` {{% boxes/note %}} 在此规范的旧版 [r0.4.0 版本](https://matrix.org/docs/spec/client_server/r0.4.0.html#cas-based-client-login) 中,如果主服务器提供 `m.login.cas` 登录流程,则可以通过 CAS 认证。本规范废弃了 `m.login.cas` 的使用,转而推荐使用 `m.login.sso`,其过程相同,仅区别在于重定向端点:对于 `m.login.cas`,使用 `/cas/redirect`,对于 `m.login.sso`,使用 `/sso/redirect`(见下文)。其他端点保持一致。 {{% /boxes/note %}} {{% definition path="api/client-server/definitions/sso_login_flow" %}} ##### 客户端行为 客户端通过引导浏览器跳转至 [`/login/sso/redirect`](/client-server-api/#get_matrixclientv3loginssoredirect) (或使用某个 `identity_providers` 时跳转至 [`/login/sso/redirect/{idpId}`](/client-server-api/#get_matrixclientv3loginssoredirectidpid)) 并携带适当的 `redirectUrl` 启动流程。认证成功后,浏览器将被重定向至该 `redirectUrl`。 {{% http-api spec="client-server" api="sso_login_redirect" %}} ###### 安全注意事项 1. 通过操控 `redirectUrl` 参数进行的 CSRF 攻击 客户端应校验对 `redirectUrl` 的任何请求。攻击者可能伪造查询参数,导致跨站请求伪造(CSRF)攻击。 例如,假设一个 Web 客户端托管于 `https://client.example.com`,希望在主服务器 [服务器名称](/appendices/#server-name) 为 `server.example.org` 上发起 SSO 登录,其通过在 `redirectUrl` 查询参数中存储服务器名实现重定向: `https://server.example.org/login/sso/redirect?redirectUrl=https://client.example.com?hs=server.example.org`。 攻击者可能诱导受害者访问 `https://server.example.org/login/sso/redirect?redirectUrl=https://client.example.com?hs=evil.com`,导致客户端将登录令牌发送到攻击者控制的 `evil.com`。 为防范此类风险,客户端不得将状态(如登录主服务器的地址)存储于任何可能被外部进程修改的位置。 状态应存储在 [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) 或 Cookie 中。 2. 为进一步安全,客户端应在 `redirectUrl` 中携带唯一标识符,并拒绝不含已知标识符的回调,以防未授权登录尝试和重放攻击。 ##### 服务器行为 服务器应注意,`identity_providers` 是可选的,较老的客户端可能无法正确解析该值。在这些情况下,客户端将使用通用的 `/redirect` 端点,而不是 `/redirect/{idpId}` 端点。 ###### 重定向到认证服务器 服务器应如下处理 `/_matrix/client/v3/login/sso/redirect`: 1. 构建适合 SSO 系统的请求。 2. 存储足够的状态信息,以便在 SSO 流程完成后能够安全恢复流程。可通过为用户浏览器设置 Cookie 的方式完成,即在响应头中添加 `Set-Cookie`。 3. 将用户浏览器重定向到 SSO 登录页,并带上合适参数。 另请参见下方“安全注意事项”。 ###### 处理认证服务器回调 通常,会有一个回调 URI 同时用于登录与用户交互式认证,由主服务器实现区分当前流程。 主服务器应验证来自 SSO 系统的响应:这可能需要对认证服务器发起附加调用,和/或验证响应中的签名。 主服务器后续操作如下: 1. 主服务器必须将认证服务器收到的用户详细信息映射为合法的 [Matrix 用户标识符](/appendices#user-identifiers)。可参见 [其他字符集的映射](/appendices#mapping-from-other-character-sets) 指南。 2. 若生成的用户标识符为新用户,则应注册为新用户。 3. 主服务器应生成一个短期登录令牌(login token)。这是一个不透明令牌,可用于以 `m.login.token` 类型调用 [`/login`](/client-server-api/#post_matrixclientv3login) API。令牌有效期建议限制在五秒左右。 4. 主服务器在最初的 `/_matrix/client/v3/login/sso/redirect` 请求所带的 `redirectUrl` 上,添加名为 `loginToken` 的查询参数,值为生成的登录令牌。(注意:`redirectURL` 可能含有已有的查询参数。若已存在一个或多个 `loginToken` 参数,应先移除后再添加新的。) 5. 主服务器将浏览器重定向到构建完成的 URI。 ##### 安全注意事项 1. 主服务器应确保登录令牌不会发送给恶意客户端。 例如,假设主服务器为 `server.example.org`。攻击者诱导受害者点击 `https://server.example.org/login/sso/redirect?redirectUrl=https://evil.com`,结果导致登录令牌发送至攻击者控制的 `evil.com`,这属于 CSRF 攻击。 为缓解风险,主服务器在处理 `/_matrix/client/v3/login/sso/redirect` 端点时,重定向到 SSO 登录页前或在认证服务器回调后,应征得用户同意,将 Matrix 账号的访问权限授予 `redirectUrl` 指定的站点。 可以设置信任白名单,仅允许已知受信任的客户端 URL。主服务器自身的 [登录回退](#login-fallback) 实现可排除在外。 2. 为进一步安全,主服务器可追踪待处理请求,防止未授权认证。可通过在处理 `/_matrix/client/v3/login/sso/redirect` 时设置 Cookie,并在从认证服务器回调时校验并清除该 Cookie 实现。 #### 用户交互式认证中的 SSO [用户交互式认证](#user-interactive-authentication-api) 适用于客户端-服务器端点,需要对用户身份进行额外确认(超出持有访问令牌以外)。通常情况下用户需要重新输入密码,但对于将认证委托给 SSO 服务器的主服务器,这意味着在用户交互式认证过程中重定向到认证服务器。 该实现基于用户交互式认证的 [回退](#fallback) 机制。 #### 客户端行为 客户端除确保实现回退机制,并将 `m.login.sso` 类型认作任意未知类型外,无需额外操作,即应为 `/_matrix/client/v3/auth/m.login.sso/fallback/web?session=` 打开浏览器窗口。流程完成后,客户端仅携带 session 重新尝试请求。 #### 服务器行为 ##### 重定向至认证服务器 服务器应以类似于 `/_matrix/client/v3/login/sso/redirect` 的方式处理 `/_matrix/client/v3/auth/m.login.sso/fallback/web`: 1. 构建适合 SSO 系统的请求。 2. 存储足够的状态信息,以便在 SSO 流程完成后能够安全恢复流程。可通过为用户浏览器设置 Cookie 的方式实现,即在响应头设置 `Set-Cookie`。 3. 将用户浏览器重定向到 SSO 登录页,并携带适当参数。 另请参阅下方“安全注意事项”。 ###### 处理来自认证服务器的回调 通常,会有单一回调 URI 同时用于登录和用户交互式认证,由主服务器确定当前流程。 主服务器应对来自 SSO 系统的响应进行验证:这可能需要对认证服务器进行额外调用,和/或验证响应的签名。 随后主服务器向用户浏览器返回[用户交互式认证回退完成](#fallback)页面。 ###### 安全注意事项 1. 操作确认 主服务器应确认用户同意继续操作。用户交互式认证的目标是防止被盗用的 `access_token` 用于接管用户账号。仅重定向到 SSO 系统远远不够,因为用户可能尚未意识到正在进行的操作,或 SSO 系统可能会自动确认认证。 例如,主服务器可向用户展示类似如下内容的页面: > 某客户端正在尝试从您的账户移除设备。请通过单点登录重新认证以确认此操作。如果此操作并非您本人发起,请警惕您的账户可能被盗用! 此操作确认可发生在重定向到 SSO 认证页前(处理 `/_matrix/client/v3/auth/m.login.sso/fallback/web` 端点时)、或认证服务器回调后。如果在认证前确认,尤其要防范下述未授权认证尝试。 2. 为进一步安全,主服务器应追踪待处理请求,防止未授权认证。例如可在处理 `/_matrix/client/v3/auth/m.login.sso/fallback/web` 时设置 Cookie,并在认证服务器回调时校验并清除该 Cookie。