WebSocket 安全
Spring Security 4.0+ 提供了对消息授权的支持。其中一个具体的应用场景是在基于 WebSocket 的应用程序中提供授权。
<websocket-message-broker>
websocket-message-broker
元素有两种不同的模式。如果未指定 websocket-message-broker@id,则它将执行以下操作:
-
确保任何
SimpAnnotationMethodMessageHandler
都已注册AuthenticationPrincipalArgumentResolver
作为自定义参数解析器。这允许使用@AuthenticationPrincipal
来解析当前Authentication
的主体。 -
确保
SecurityContextChannelInterceptor
自动注册到clientInboundChannel
。这会用消息中找到的用户填充SecurityContextHolder
。 -
确保
ChannelSecurityInterceptor
已注册到clientInboundChannel
。这允许为消息指定授权规则。 -
确保
CsrfChannelInterceptor
已注册到clientInboundChannel
。这确保只有来自原始域的请求才被启用。 -
确保
CsrfTokenHandshakeInterceptor
已注册到WebSocketHttpRequestHandler
、TransportHandlingSockJsService
或DefaultSockJsService
。这确保将HttpServletRequest
中预期的CsrfToken
复制到 WebSocket 会话属性中。
如果需要额外的控制,可以指定 id,并且会将 ChannelSecurityInterceptor
分配给指定的 id。然后可以手动完成与 Spring 的消息传递基础架构的所有连接。这样虽然更繁琐,但提供了对配置更大的控制。
<websocket-message-broker> 属性
-
id 一个 bean 标识符,用于在上下文的其他地方引用
ChannelSecurityInterceptor
bean。如果指定了该标识符,Spring Security 就需要在 Spring Messaging 中进行显式配置。如果没有指定,Spring Security 将会按照 <websocket-message-broker> 中描述的方式自动与消息传递基础设施集成。 -
same-origin-disabled 禁用在 Stomp 头中必须存在 CSRF 令牌的要求(默认为 false)。如果需要允许其他来源建立 SockJS 连接,则更改默认值是有用的。
-
authorization-manager-ref 使用此
AuthorizationManager
实例;当设置时,use-authorization-manager
被忽略并假定为true
-
use-authorization-manager 使用
AuthorizationManager
API 而不是SecurityMetadataSource
API(默认为 true)。 -
security-context-holder-strategy-ref 使用此
SecurityContextHolderStrategy
(注意仅支持与AuthorizationManager
API 结合使用)
<websocket-message-broker> 的子元素
<intercept-message>
定义消息的授权规则。
<intercept-message> 的父元素
<intercept-message> 属性
-
pattern 一个基于 ant 的模式,用于匹配消息目标。例如,"/" 匹配任何具有目标的消息;"/admin/" 匹配任何目标以 "/admin/**" 开头的消息。
-
type 要匹配的消息类型。有效值在 SimpMessageType 中定义(即 CONNECT、CONNECT_ACK、HEARTBEAT、MESSAGE、SUBSCRIBE、UNSUBSCRIBE、DISCONNECT、DISCONNECT_ACK、OTHER)。
-
access 用于保护消息的表达式。例如,"denyAll" 将拒绝所有匹配消息的访问;"permitAll" 将授予所有匹配消息的访问权限;"hasRole('ADMIN')" 要求当前用户对匹配的消息具有 'ROLE_ADMIN' 角色。