How to get Authentication from X-Auth-Token?

↘锁芯ラ 提交于 2021-01-29 15:35:32

问题


My goal is to authenticate the WebSocket CONNECT frame. I wish to be able to initialize Authentication user = ... by using X-Auth-Token.

TL:DR

I use the X-Auth-Token header. How the current authentication works:

  1. User hit POST /login endpoint with Form Data username and password.
  2. The response header will contain the key X-Auth-Token.
  3. If you hit any REST endpoint with X-Auth-Token the server will recognize the user.
  4. The issue is how to get Authentication from X-Auth-Token in the WebSocket CONNECT frame.

The current solution is to use JWT, however, one of the requirements for this project is a user should be able to invalidate the session. For JWT to be able to do that, the JWT should be a stateful, reference to this SO's the question

@Configuration
@EnableWebSocketMessageBroker
// see: https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#websocket-stomp-authentication-token-based
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
public class WebSocketAuthenticationConfig implements WebSocketMessageBrokerConfigurer {
  @Override
  public void configureClientInboundChannel(ChannelRegistration registration) {
    registration.interceptors(new ChannelInterceptor() {
      @Override
      public Message<?> preSend(Message<?> message, MessageChannel channel) {
        StompHeaderAccessor accessor =
                MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
        if (StompCommand.CONNECT.equals(accessor.getCommand())) {
          String sessionId = accessor.getFirstNativeHeader("X-AUTH-TOKEN");
//          Authentication user; // How to get Authentication from X-Auth-Token?
//          accessor.setUser(user);
        }
        return message;
      }
    });
  }
}

What I did:

  1. I change Cookie-based authentication by letting the session be provided in a header.
// see: https://docs.spring.io/spring-session/docs/current/reference/html5/#httpsession-rest
@Configuration
// Override HttpSession's Filter, in this instance Spring Session is backed by Redis.
@EnableRedisHttpSession
public class HttpSessionConfig {

  // Default connection configuration, to localhost:6739.
  @Bean
  public LettuceConnectionFactory connectionFactory() {
    return new LettuceConnectionFactory();
  }

  // Tell Spring to use HTTP headers, X-Auth-Token.
  @Bean
  public HttpSessionIdResolver httpSessionIdResolver() {
    return HeaderHttpSessionIdResolver.xAuthToken();
  }
}
  1. logic to CONNECT and SUBSCRIBE
const X-Auth-Token = "" // get from the POST `/login` endpoint

const onConnectCallback = () => {
  const destinations = ["/topic/channel/1", "/user/queue/messages"];
  for (let i = 0; i < destinations.length; i++) {
    stompClient.subscribe(destinations[i], (payload) => {
      // receiveMessageCallback
    });
  }
};

const stompConfig = {
  brokerURL: "ws://localhost:8080/chat",
  connectHeaders: {
    "X-Auth-Token": X_Auth_Token,
  },
  onConnect: onConnectCallback,
};
const stompClient = new StompJs.Client(stompConfig);
stompClient.activate();

Reference

I am worried that X-Auth-Token is not supported in WebSocket because based on SO's answer there is no API to retrieve session by id

来源:https://stackoverflow.com/questions/65930974/how-to-get-authentication-from-x-auth-token

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!