认证
每个通过WebSocket消息会话进行的STOMP通信都始于一个HTTP请求。该请求可以是用于升级到WebSocket的请求(即WebSocket握手),或者在SockJS回退机制的情况下,是一系列SockJS HTTP传输请求。
许多Web应用程序已经实现了认证和授权机制来保护HTTP请求。通常,用户通过Spring Security进行认证,使用的方法可能是登录页面、HTTP基本认证或其他方式。经过认证的用户的安全上下文会保存在HTTP会话中,并通过相同的基于cookie的会话与后续请求关联起来。
因此,对于WebSocket握手或SockJS HTTP传输请求,通常已经有一个通过HttpServletRequest#getUserPrincipal()可以访问的已认证用户。Spring会自动将该用户与为他们创建的WebSocket或SockJS会话关联起来,随后,通过用户头(user header)将该用户与通过该会话传输的所有STOMP消息关联起来。
简而言之,一个典型的Web应用程序在安全性方面无需做任何超出其现有功能的事情。用户在HTTP请求级别进行身份验证,这种身份验证通过基于cookie的HTTP会话来维护(该HTTP会话随后会与为该用户创建的WebSocket或SockJS会话关联起来),从而在流经应用程序的每个Message上都会附带一个用户头部信息。
STOMP协议在CONNECT帧中确实包含login和passcode头字段。这些字段最初是为通过TCP传输的STOMP通信设计的,也是必需的。然而,对于通过WebSocket传输的STOMP通信,默认情况下,Spring会忽略STOMP协议层上的认证头信息,并假设用户已经在HTTP传输层完成了认证。在这种情况下,WebSocket或SockJS会话中应该包含已经认证的用户信息。