认证
每个基于 WebSocket 的 STOMP 消息会话都始于一个 HTTP 请求。这可以是一个升级到 WebSocket 的请求(即 WebSocket 握手),或者在 SockJS 回退的情况下,是一系列 SockJS HTTP 传输请求。
许多 Web 应用已经有认证和授权来保护 HTTP 请求。通常,用户通过 Spring Security 使用登录页面、HTTP 基本认证或其他方式进行认证。已认证用户的安全上下文保存在 HTTP 会话中,并与同一基于 Cookie 的会话中的后续请求相关联。
因此,对于 WebSocket 握手或 SockJS HTTP 传输请求,通常已经有一个已认证用户可以通过 HttpServletRequest#getUserPrincipal()
访问。Spring 会自动将该用户与其创建的 WebSocket 或 SockJS 会话关联起来,随后通过用户头将该会话上的所有 STOMP 消息与之关联。
简而言之,典型的 Web 应用除了已有的安全措施外,不需要做额外的事情。用户在 HTTP 请求层面通过基于 Cookie 的 HTTP 会话(然后与为其创建的 WebSocket 或 SockJS 会话关联)维护的安全上下文进行认证,这导致流经应用中的每条 Message
都带有用户头。
STOMP 协议在 CONNECT
帧上确实有 login
和 passcode
头。这些最初是为基于 TCP 的 STOMP 设计并必需的。然而,对于基于 WebSocket 的 STOMP,Spring 默认忽略 STOMP 协议层面的认证头,并假定用户已在 HTTP 传输层面进行认证。期望是 WebSocket 或 SockJS 会话包含已认证用户。