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 帧上有 login 和 passcode 标头。这些最初是为 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.