Long Polling의 모든 응답에서 401 Error 발생

호기성세균·2024년 6월 19일
0

트러블슈팅

목록 보기
17/20
post-thumbnail
  1. 모든 응답이 401로 의도한 대로 응답이 발생하지 않았습니다.

  2. 오류 발생 가능성이 있는 지점에 브레이크 포인트를 지정하고 디버그 모드로 순차적으로 점검하였습니다.

  • 생성로직 -> 문제 없었습니다.
  • 작성로직 -> 문제 없었습니다.
  • Dto -> 문제 없었습니다.
  • 디버그 결과 내부 로직에서는 문제를 발견하지 못했습니다.
  1. 401 에러가 우리 코드문제인지 시큐리티 문제인지 찾기 위해 시큐리티 엔트리포인트 에러 메시지를 변경 -> 시큐리티 에러 메시지를 확인했습니다.

  2. DeferredResult 401 로 검색

  3. 스프링 시큐리티에서 응답시에도 SecurityContext를 읽어 권한체크를 하는데 이 때 다른 스레드에서 처리되어 인정권한을 읽어버리는 문제였음

  • 비동기 요청을 처리하는 과정
    image
  • Spring Security 6 버전부터 SecurityContext를 관리하는 기본 방식인 SecurityContextHolderFilter를 사용합니다. SecurityContextHolderFilter는 이전 버전과 달리 SecurityContextRepository에 구현체를 등록하지 않으면 인증된 객체를 저장할 수 없기 때문입니다. DeferredResult는 응답 시 다른 스레드에 의해서 인증을 한 번 더 하게 되는데 이 경우 SecurityContext를 가져올 방법이 없어 401 에러가 발생했습니다.
  1. 시큐리티 설정 추가
 http.securityContext((securityContext) -> securityContext
        .securityContextRepository(new DelegatingSecurityContextRepository(
                new RequestAttributeSecurityContextRepository(),
                new HttpSessionSecurityContextRepository()
        ))
);
  1. 해결
  • DelegatingSecurityContextRepository
    • SecurityContextRepository 구현체를 체인으로 연결합니다.
    • 연결된 목록을 순회하며 SecurityContext를 저장하거나 복원하는데 사용됩니다.
  • RequestAttributeSecurityContextRepository
    • SecurityContext를 HTTP 요청의 속성으로 저장하고 복원할 때 사용됩니다.
    • 현재 요청을 처리하는 동안 스레드 간 SecurityContext를 올바르게 전파하여 비동기 작업의 문제점을 해결 할 수 있습니다.
    • SecurityContext를 세션에 저장하고 복원합니다.
    • 현재 세션을 공유하는 모든 스레드에서 SecurityContext가 올바르게 전파될 수 있도록 합니다.

레퍼런스

profile
공부...열심히...

0개의 댓글