Skip to content

身份验证 (Authentication)

每个基于 WebSocket 的 STOMP 消息会话都始于一个 HTTP 请求。这可能是一个升级到 WebSocket 的请求(即 WebSocket 握手),或者在 SockJS 备选方案的情况下,是一系列 SockJS HTTP 传输请求。

基于 HTTP 的验证

由于 WebSocket 始于 HTTP,许多 Web 应用程序已经具备了保护 HTTP 请求的身份验证和授权机制。通常,用户通过 Spring Security 使用登录页面、HTTP 基本认证等方式进行身份验证。

  • 安全上下文: 经过身份验证的用户安全上下文会保存在 HTTP Session 中。
  • 关联性: 对于 WebSocket 握手或 SockJS 请求,通常已经可以通过 HttpServletRequest#getUserPrincipal() 访问到已认证的用户。Spring 会自动将该用户与为他们创建的 WebSocket 或 SockJS 会话相关联。

简单来说: 典型的 Web 应用程序不需要做任何额外工作。用户已在 HTTP 请求级别通过基于 Cookie 的会话进行了身份验证,这使得每一个流经应用程序的 Message 都会被自动盖上用户标头。

STOMP CONNECT 帧验证

STOMP 协议在 CONNECT 帧上有 loginpasscode 标头。这些最初是为 STOMP over TCP 设计的。

然而,对于 STOMP over WebSocket,Spring 默认忽略 STOMP 协议级别的身份验证标头,并假设用户已经在 HTTP 传输级别通过了认证。


补充教学

1. 为什么“复用” HTTP 登录是最佳实践?

WebSocket 的安全性本质上依赖于起始的 HTTP 握手。既然你已经有了成熟的 Spring Security 配置(处理 CSRF、Session 管理、OAuth2 等),直接复用这些机制比在 WebSocket 内部再搞一套登录逻辑要安全且简单得多。

2. Spring Security 的角色

只要你的 Spring Security 配置允许握手路径(如 /portfolio)被访问,并且用户当时已经登录,Spring 就会把 Principal 对象从 HTTP 线程无缝传递到 WebSocket 消息处理线程。

3. 如果没有 Session 怎么办?

在某些无状态(Stateless)应用或移动端应用中,Cookie 可能不适用。在这种情况下,你需要采用基于令牌的身份验证

Based on Spring Framework.