웹소켓 STOMP 쿠키 기반 인증 도입 및 SEND 커맨드 실시간 검증#231
Conversation
7ebc66e to
33b06d1
Compare
📊 코드 커버리지 리포트
|
| if (sessionAttributes != null && sessionAttributes.containsKey("accessToken")) { | ||
| token = (String)sessionAttributes.get("accessToken"); | ||
| } | ||
|
|
||
| if (jwtTokenProvider.validateAccessToken(token)) { | ||
| Authentication authentication = jwtTokenProvider.getAuthentication(token); | ||
| accessor.setUser(authentication); | ||
| if (token == null && StompCommand.CONNECT.equals(command)) { | ||
| String authorizationHeader = accessor.getFirstNativeHeader(JwtKeys.Headers.AUTHORIZATION); | ||
|
|
||
| if (authorizationHeader != null && authorizationHeader.startsWith(JwtKeys.Headers.BEARER_PREFIX)) { | ||
| token = authorizationHeader.substring(JwtKeys.Headers.BEARER_PREFIX.length()); | ||
|
|
||
| if (sessionAttributes != null) { | ||
| sessionAttributes.put("accessToken", token); | ||
| } |
There was a problem hiding this comment.
이 부분은 의도를 한번 확인해보고 싶습니다.
이전 JWT 인증 쪽 논의에서는 Authorization 헤더를 우선 보고, 필요할 때 쿠키를 fallback으로 사용하는 흐름이 있었던 것으로 기억하는데요. 현재 WebSocket 쪽 구현은 세션/쿠키에 저장된 accessToken이 있으면 그 값을 먼저 사용하고, 없을 때만 CONNECT 헤더를 보는 구조라서 우선순위가 조금 달라 보였습니다.
그래서 브라우저에 남아 있는 쿠키 토큰이 오래된 상태이고, 클라이언트가 더 최신 토큰을 헤더로 보내는 경우에는 헤더 값이 반영되지 못할 수도 있을 것 같아서요.
혹시 쿠키 값을 항상 우선하도록 의도하신 걸까요? 만약 쿠키/헤더 하이브리드 지원을 생각하신 거라면, CONNECT 시점에는 헤더를 우선 적용하고 그 값을 세션에 갱신하는 쪽도 더 자연스러울 수 있을 것 같아 의견 여쭙습니다.
There was a problem hiding this comment.
일반 API와 달리, 소켓 통신 인증에서는 쿠키에 저장된 토큰을 최우선으로 사용하기로 결정했기 때문에 세션/쿠키를 먼저 확인하도록 구현했습니다.
CONNECT 시점의 헤더 확인 로직은 정상적인 흐름이라기보다는, 쿠키 세팅이 불가피하게 누락되는 만약의 경우를 대비한 방어 로직으로 남겨둔 것입니다.
There was a problem hiding this comment.
설명 주신 의도는 이해했습니다. 웹소켓에서는 쿠키/세션을 우선하고, 헤더는 예외 상황 fallback으로 두신 거군요.
그 기준으로 보면 현재 통합 테스트는 Authorization 헤더만 사용해서 연결하고 있어서, 실제 주 경로인 쿠키 기반 handshake/auth 흐름을 직접 검증하고 있지는 않은 것 같습니다. 혹시 가능하다면 accessToken 쿠키를 실어서 연결하는 케이스도 하나 추가해두면, 이번 PR의 핵심 동작을 더 정확하게 보장할 수 있을 것 같은데 어떻게 생각하시나요?
There was a problem hiding this comment.
좋은 의견 감사합니다! 짚어주신 대로 현재 테스트가 Fallback 경로인 Authorization 헤더에만 맞춰져 있어서, 주 경로인 쿠키 기반의 인증 흐름에 대한 검증이 누락되어 있었네요. 핵심 동작을 더 확실히 보장할 수 있도록 accessToken 쿠키를 사용하는 테스트 케이스를 바로 추가하겠습니다.
There was a problem hiding this comment.
@Goder-0 쿠키 기반 인증 방식으로 테스트 코드 수정완료하였습니다. 확인부탁드립니다
|
PR에 이슈 번호 연결해주세요. |
- [WebSocketConfig] HTTP Handshake 시 accessToken 쿠키를 웹소켓 세션으로 복사하는 HandshakeInterceptor 추가 - [StompHandler] STOMP CONNECT 시 세션(쿠키) 토큰과 헤더 토큰을 모두 지원하도록 하이브리드 인증 로직 구현
33b06d1 to
9f7a57f
Compare
Goder-0
left a comment
There was a problem hiding this comment.
작업이 완료되었다고 판단되어 승인합니다.
한편, 프론트 대응작업으로 Team-SoFa/linkiving#518 이슈를 생성하였습니다. 해당 이슈를 해결하는 PR이 올라온 이후 머지가 되는것이 좋을 것 같습니다.
관련 이슈
PR 설명
CONNECT) 시점에만 헤더를 통해 인증을 수행하여, 연결 이후 토큰이 만료되거나 비정상적인SEND요청이 들어올 때 이를 방어하지 못하는 보안 취약점이 있었습니다.SEND) 시점마다 토큰의 유효성을 실시간으로 검증하도록 인증 아키텍처를 크게 개선했습니다.작업 내용
1. 웹소켓 엔드포인트 보안 정책 강화 (
SecurityConstants)PERMIT_URLS에 포함되어 무조건 허용되던 웹소켓 경로(/ws/chat/**,/ws/link/**)를 제거하여, 기본적인 Spring Security 인증 정책의 보호를 받도록 변경했습니다.2. 쿠키 기반 Handshake 인터셉터 추가 (
WebSocketConfig)HandshakeInterceptor를 추가했습니다.accessToken을 추출하여 STOMP 세션 정보(attributes)에 저장해 둠으로써, 이후 TCP 통신 단계에서도 토큰 정보에 접근할 수 있도록 하이브리드 인증 기반을 마련했습니다.3. SEND 커맨드 JWT 실시간 검증 (
StompHandler)ChannelInterceptor의preSend로직을 개선하여,CONNECT뿐만 아니라SEND커맨드 유입 시에도 인증을 수행하도록 분기를 확장했습니다.validateAccessToken)하며, 만료되거나 유효하지 않은 토큰으로 메시지를 전송하려 할 경우MessagingException을 발생시켜 원천 차단합니다.