Spring 网络套接字。在 Config 中获取对 Cookie 的访问权限
Spring WebSocket. Get access to Cookie in Config
我正在尝试通过 Spring 使用 STOMP、OAuth 2 和 SockJS 配置 WebSocket。
新规范 tells us 如何使用拦截器实现它。
情况是:如果用户通过身份验证,则在 CONNECT 请求的 Native header 中有一个 Bearer Token,并且通过 Token 设置主体没有问题。
但我的任务是对未经授权的用户使用 BrowserToken(保存在 Cookies 中)。我怎样才能从请求中得到它?
我找到了解决方案:
@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;
}
});
}
我正在尝试通过 Spring 使用 STOMP、OAuth 2 和 SockJS 配置 WebSocket。 新规范 tells us 如何使用拦截器实现它。 情况是:如果用户通过身份验证,则在 CONNECT 请求的 Native header 中有一个 Bearer Token,并且通过 Token 设置主体没有问题。 但我的任务是对未经授权的用户使用 BrowserToken(保存在 Cookies 中)。我怎样才能从请求中得到它?
我找到了解决方案:
@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;
}
});
}