我为
spring-web app添加了基于自定义令牌的身份验证,并为spring websocket扩展了相同的身份验证,如下所示
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic","/queue"); config.setApplicationDestinationPrefixes("/app"); config.setUserDestinationPrefix("/user"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("*").withSockJS(); } @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); if (StompCommand.CONNECT.equals(accessor.getCommand())) { String jwtToken = accessor.getFirstNativeHeader("Auth-Token"); if (!StringUtils.isEmpty(jwtToken)) { Authentication auth = tokenService.retrieveUserAuthToken(jwtToken); SecurityContextHolder.getContext().setAuthentication(auth); accessor.setUser(auth); //for Auth-Token '12345token' the user name is 'user1' as auth.getName() returns 'user1' } } return message; } }); } }
var socket = new SockJS('http://localhost:8080/gs-guide-websocket'); stompClient = Stomp.over(socket); stompClient.connect({'Auth-Token': '12345token'},function (frame) { stompClient.subscribe('/user/queue/greetings',function (greeting) { alert(greeting.body); }); });
从我的控制器我发送消息为
messagingTemplate.convertAndSendToUser("user1","/queue/greetings","Hi User1");
对于auth令牌12345token,用户名是user1.但是当我向user1发送消息时,它没有在客户端收到.这有什么我想念的吗?
解决方法
在您的Websocket控制器中,您应该执行以下操作:
@Controller public class GreetingController { @Autowired private SimpMessagingTemplate messagingTemplate; @MessageMapping("/hello") public void greeting(Principal principal,HelloMessage message) throws Exception { Greeting greeting = new Greeting(); greeting.setContent("Hello!"); messagingTemplate.convertAndSendToUser(message.getToUser(),"/queue/reply",greeting); } }
在客户端,您的用户应订阅topic / user / queue / reply.
您还必须添加一些目标前缀:
@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableSimpleBroker("/topic","/queue","/user"); config.setApplicationDestinationPrefixes("/app"); config.setUserDestinationPrefix("/user"); } /*...*/ }
当您的服务器在/ app / hello队列上收到消息时,它应该向您的dto中的用户发送消息.用户必须等于用户的主体.
我认为您的代码中唯一的问题是您的“/ user”不在您的目标前缀中.您的问候语消息被阻止,因为您将它们发送到以/ user开头的队列中,并且未注册此前缀.
你可以在git repo上查看来源:
https://github.com/simvetanylen/test-spring-websocket
希望它有效!