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