我有websocket配置类:
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topics");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/notifications").setAllowedOrigins("*").withSockJS();
}
和ClientInboundChannel
一样:
@Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.setInterceptors(new ChannelInterceptorAdapter() {
@Override
public Message<?> preSend(Message<?> message, MessageChannel channel) {
StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
final String xAuthToken = accessor.getFirstNativeHeader(ManipulatesHeaders.X_AUTH_TOKEN_HEADER);
if (xAuthToken == null) {
return message;
}
final UserDetails userDetails = authService.getUserDetails(xAuthToken);
if (StompCommand.CONNECT == accessor.getCommand()) {
final WebSocketPrincipal principal = (...)
userRegistry.registerUser(principal, message);
accessor.setUser(principal);
}
return message;
}
}
}
现在,我想向订阅特定频道的每个用户发送欢迎消息。很明显,可以通过创建一个实现ApplicationListener<SessionSubscribeEvent>
并提供的类来实现
@Override
public void onApplicationEvent(final SessionSubscribeEventevent) {
StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());
}
第二种方法是在上述ClientInboundChannel
中执行类似的事情(它是相同的)。
问题是,当用户发送staz simpUser
时,message
中没有SUBSCRIBE
标头。
过程如下:用户发送stomp CONNECT
,执行此行:accessor.setUser(principal)
,此时message
已正确设置simpUser
标头。但是当在SUBSCRIBE
收到stomp preSend
消息时,StompHeaderAccessor
没有simpUser
标题。因此,我无法评估用户是否已经过身份验证。
那么如何检查发送SUBSCRIBE
消息的用户是否已经过身份验证? (以及为什么经过身份验证的用户不会发送simpUser
标头)
在您的websocket配置类中,将您的扩展名更改为AbstractSecurityWebSocketMessageBrokerConfigurer
然后您可以按如下方式设置安全性:
@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry message) {
message
.nullDestMatcher().permitAll()
.simpDestMatchers("/app/**").authenticated()
.simpSubscribeDestMatchers("/topics/**").authenticated()
.anyMessage().denyAll();
}
如果你得到错误Could not verify the provided CSRF token because your session was not found
你将不得不覆盖websocket配置类中的`sameOriginDisabled
@Override
protected boolean sameOriginDisabled() {
return true;
}
有关websocket安全性的更多信息:
https://docs.spring.io/spring-security/site/docs/current/reference/html/websocket.html