使用JWT保护WebSocket(Spring + React)

时间:2018-07-23 16:04:44

标签: reactjs spring-boot jwt spring-websocket

我想在春季引导中保护Websocket。到目前为止,我已经成功地设法保护了正常的http请求,但是websockets出现了问题。我希望能够确保安全,然后再将消息发送给特定用户。根据这些消息来源:

我写了这段代码:

@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
@Slf4j
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Autowired
    private JwtTokenProvider jwtTokenProvider;

    @Autowired
    private CustomUserServiceDetails customUserServiceDetails;



    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic", "/queue");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/voting-socket").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 header = accessor.getFirstNativeHeader("Authorization");

                    log.info("Header auth token: " + header);

                    String jwt = JwtTokenProvider.getToken(header);

                    log.info("Token only : " + jwt);

                    if (StringUtils.hasText(jwt) && jwtTokenProvider.validateToken(jwt)) {
                        Long userId = jwtTokenProvider.getUserIdFromJWT(jwt);

                        User user = (User) customUserServiceDetails.loadUserById(userId);

                        Principal principal = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());

                        if (Objects.isNull(principal))
                            return null;

                        accessor.setUser(principal);
                    } else if (StompCommand.DISCONNECT.equals(accessor.getCommand())) {
                        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

                        if (Objects.nonNull(authentication))
                            log.info("Disconnected Auth : " + authentication.getName());
                        else
                            log.info("Disconnected Sess : " + accessor.getSessionId());
                    }
                }

                return message;
            }



        });
    }
}

,这按预期方式工作(身份验证有效)。但是现在当我想添加用户注册表时:

@Autowired
private SimpUserRegistry userRegistry;

我的代码根本不执行(但是没有得到关于接线或其他任何错误的信息)。我在这里做错了什么?也许我应该使用一些差异方法。我的主要目标再次是:

  • 身份验证
  • 使用converAndSendToUser方法的能力。

0 个答案:

没有答案