2016-12-28 324 views
2

我想通过STOMP,OAuth 2和SockJS通过Spring配置WebSocket。 新规格tells us如何使用拦截器来实现它。 这种情况是:如果用户通过认证,CONNECT请求的本地报头中有一个承载令牌,并且通过令牌设置主体没有问题。 但我的任务是将BrowserToken用于未经授权的用户(保存在Cookies中)。我如何从请求中获得它?Spring WebSocket。获取访问配置Cookie

+0

我想这将是愚蠢的浏览器发送令牌在本地头从UI(这些信息存储在一点点无论如何,Cookie都会随着请求来到后端)。 – Tolledo

+1

我想你应该看看'HandshakeInterceptor'并从'HttpServletRequest'中提取Cookie –

回答

3

我已经找到了解决办法:

@Override 
public void registerStompEndpoints(StompEndpointRegistry registry) { 
    registry.addEndpoint("/websocket/tracker") 
     .withSockJS() 
     .setInterceptors(httpSessionHandshakeInterceptor()); 
} 
@Bean 
public HandshakeInterceptor httpSessionHandshakeInterceptor() { 
    return new HandshakeInterceptor() { 
     @Override 
     public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { 
      if (request instanceof ServletServerHttpRequest) { 
       ServletServerHttpRequest servletServerRequest = (ServletServerHttpRequest) request; 
       HttpServletRequest servletRequest = servletServerRequest.getServletRequest(); 
       Cookie token = WebUtils.getCookie(servletRequest, "key"); 
       attributes.put("token", token.getValue()); 
      } 
      return true; 
     } 
     @Override 
     public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { 
     } 
    }; 
} 

最后

@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())) { 
       Map<String, Object> sessionAttributes = accessor.getSessionAttributes(); 
       List<String> authorization = accessor.getNativeHeader("Authorization"); 
       Principal user = ... ; // get Principal using authentication/browser token 
       accessor.setUser(user); 
      } 

      return message; 
     } 
    }); 
}