【问题标题】:Access JWT token in Spring Boot with Stomp使用 Stomp 在 Spring Boot 中访问 JWT 令牌
【发布时间】:2022-01-14 16:31:49
【问题描述】:

我已经按照this guide 设置了 ng2-stompjs,但是在我的 Spring 引导后端遇到问题,因为我使用的是 JWT 令牌。

首先,由于我的 JWT 安全性,stomp 服务不想连接,所以我将其添加到安全配置中:

安全配置:

http.authorizeRequests().antMatchers("/websockets").permitAll();

WebSocket配置

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/websockets").setAllowedOrigins("*");
}

我的前端 stomp 配置:

import { InjectableRxStompConfig } from '@stomp/ng2-stompjs';

export const myRxStompConfig: InjectableRxStompConfig = {
  // Which server?
  brokerURL: 'ws:/localhost:3000/websockets',

  // How often to heartbeat?
  // Interval in milliseconds, set to 0 to disable
  heartbeatIncoming: 0, // Typical value 0 - disabled
  heartbeatOutgoing: 20000, // Typical value 20000 - every 20 seconds

  // Wait in milliseconds before attempting auto reconnect
  // Set to 0 to disable
  // Typical value 500 (500 milli seconds)
  reconnectDelay: 200,

  // Will log diagnostics on console
  // It can be quite verbose, not recommended in production
  // Skip this key to stop logging to console
  debug: (msg: string): void => {
    console.log(new Date(), msg);
  },

  beforeConnect: (stompClient: any): Promise<void> => {
    const token = localStorage.getItem('JWT_TOKEN');
    return new Promise<void>((resolve, _) => {
      stompClient.connectHeaders = {
        Authorization: 'Bearer ' + token, //also tried x-auth-token
      };
      resolve();
    });
  },
};

以及我使用套接字的组件(注意:如果目的地不正确,请忽略,我只是在测试):

ngOnInit(): void {
  this.rxStompService.watch('/topic/test').subscribe((message: Message) => {
    console.log(message.body);
  });
}

public test(): void {
  this.rxStompService.publish({ destination: '/hello' });
}

有没有办法实际附加令牌?请注意,我使用的是刷新令牌,因此每 10 分钟会生成一个新的访问令牌,并且必须为每个请求使用一个新的访问令牌。

其次,如何在 spring 端点中提取令牌?在其他情况下,我会使用HttpServletRequest 并提取授权标头,但是如何使用套接字执行此操作?我需要这个,因为我需要使用发出请求的人的用户名(一个简单的解决方法是在正文中传递用户名,但如果可能的话,我希望用 JWT 保护它)。

@MessageMapping("/hello")
@SendTo("/topic/test")
public void createGameMP(HttpServletRequest request) {
    log.info("HI");
    log.info(request.getHeader(AUTHORIZATION).substring("Bearer ".length())); // obvious error
}

【问题讨论】:

    标签: angular spring spring-boot sockets jwt


    【解决方案1】:

    你可以使用Interceptor拦截websocket请求并在请求中设置token。

    1. 定义自定义 HandshakeInterceptor
    public class MyHandshakeInterceptor implements HandshakeInterceptor {
    
        private final static String X_AUTH_TOKEN = "x-auth-token";
    
        @Override
        public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes)
                throws Exception {
            
            if (request instanceof ServletServerHttpRequest) {
                ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
                HttpServletRequest httpServletRequest = servletRequest.getServletRequest();
                String token = httpServletRequest.getParameter(X_AUTH_TOKEN);
                if (null == token) {
                    httpServletRequest.setParameter(X_AUTH_TOKEN, "xxxxx");//todo token value
                }
            }
            return true;
        }
    }
    
    1. 配置
    @Bean
    public HandshakeInterceptor getHandshakeInterceptor() {
        return new MyHandshakeInterceptor();
    }
    
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/wse").setAllowedOrigins("*").setInterceptors(myHandshakeInterceptor);
        registry.addEndpoint("/wss").setAllowedOrigins("*").setInterceptors(myHandshakeInterceptor);
    }
    

    【讨论】:

    • 似乎无法正常工作。 httpServletRequest.getParameter("x-auth-token") 为空。我猜我必须在前端的 stomp 配置中设置 beforeConnect,但它仍然不起作用。我在原始帖子中编辑了 rxStompConfig 以显示我所做的更改。
    • @qlabfgerkaSmurf 您好,您可以实现ChannelInterceptor 并覆盖afterSendCompletion() 方法,设置令牌以在StompCommand CONNECT 时请求。然后就可以在Interceptor中获取token了。
    猜你喜欢
    • 2019-07-21
    • 2021-03-12
    • 2017-02-06
    • 2020-01-18
    • 1970-01-01
    • 2020-03-01
    • 2019-12-08
    • 2020-04-23
    • 2020-02-12
    相关资源
    最近更新 更多