ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • WebSocket 연결 시, JWT Token Error
    트러블슈팅 2024. 8. 15. 20:29

    문제

    다른 요청에 대해서는 header의 token을 정상적으로 가져오지만 Web Socket의 요청에서 계속 Spring Security Context 에서 사용자의 정보를 가져올 때, 에러가 발생했다.


    원인

    • 정상적인 요청
    Jul 23 09:24:38 ip-172-31-44-203 web[1099434]: token : Bearer aaaaaaaaabbbbbbbbbbbcccccccc
    • websocket 의 요청
    Jul 23 09:22:29 ip-172-31-44-203 web[1099434]: token : null
    • http와 WebSocket의 Security chain, config는 완전히 독립적이다.
    • 기존 AuthenticationProvider는 Websocket Authentication에 관여하지 않는다.
    • Websocket에 CONNECT 되면 해당 user는 websocket session에 저장되며 이후 메세지에는 인증 과정을 거치지 않는다.

    해결

    - WebSocketConfig

      @Override
        public void configureClientInboundChannel(ChannelRegistration registration) {
            registration.interceptors(stompHandler);
        }
    

     

    - StompHandler

    @Component
    @RequiredArgsConstructor
    public class StompHandler implements ChannelInterceptor {
    
        private final JwtUtil jwtUtil;
    
        @Override
        public Message<?> preSend(Message<?> message, MessageChannel channel) {
            StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
            String accessToken = "";
            // 연결 요청에 대해 실행
            if(accessor.getCommand() == StompCommand.CONNECT) {
                accessToken = accessor.getFirstNativeHeader("Authorization");
            }
    
            if (StringUtils.hasText(accessToken) && accessToken.startsWith("Bearer ")) {
                accessToken = accessToken.substring(7);
            }
    
            try {
                jwtUtil.validateAccessToken(accessToken);
            } catch (ExpiredJwtException e) {
                throw new CatchStudyException(ErrorCode.EXPIRED_ACCESS_TOKEN);
            }
    
            Authentication authentication = jwtUtil.getAuthentication(accessToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            accessor.setUser(authentication);
    
            return message;
        }
    }
    
    

    WebSocketConfig에 ChannelInterceptor를 구현한 클래스를 만들어 stomp 메시지 헤더에 접근해 socket이 연결되었을 때,

    token을 검증하도록 했다.

Designed by Tistory.