Spring Security를 사용해 JWT 기반 인증 및 인가를 구현하던 중, 특정 상황에서 예상치 못한 HTTP 403(Forbidden) 상태 코드가 반환되는 문제가 발생했습니다. 이는 에러 상황에서 올바른 상태 코드와 메시지가 반환되지 않아, 문제의 원인을 파악하기 어렵게 만들었습니다.
문제가 발생한 증상은 다음과 같았습니다:
처음에는 JWT에서 추출된 역할(Role) 정보가 SecurityContextHolder
에 제대로 전달되지 않았거나, Spring Security 설정에 문제가 있을 가능성을 의심했습니다. 디버깅 도구와 로그를 활용해 요청 플로우를 조사하기 시작했습니다.
우선, SecurityContextHolder
에 저장된 역할 정보와 Spring Security 설정을 집중적으로 분석했습니다. 디버깅 결과:
SecurityContextHolder
에는 올바른 역할 정보가 포함되어 있었고,이로 인해 문제가 요청 플로우에서 발생하지 않는다는 점을 확인했습니다. 이후, DispatcherServlet
의 흐름을 추적하며 문제가 응답 플로우에서 발생하고 있음을 발견했습니다.
추적 결과, 에러가 발생했을 때 DispatcherServlet
이 서블릿 컨테이너를 통해 /error
엔드포인트로 요청을 포워드하고 있었습니다. 예상과 달리, 요청 플로우가 아니라 응답 플로우 중에 /error
엔드포인트가 호출되며 문제가 발생하고 있었습니다. /error
엔드포인트는 Spring Security 설정에서 보호되고 있었기 때문에, 해당 엔드포인트에 접근이 차단되며 HTTP 403 상태 코드가 반환되고 있었습니다.
이로 인해 에러 상황에서도 적절한 상태 코드와 메시지가 반환되지 않아, 디버깅과 문제 해결이 거의 불가능한 상태였습니다.
문제를 해결하기 위해 Spring Security 설정에서 /error
엔드포인트에 대한 접근을 허용하는 규칙을 추가했습니다. 다음은 수정된 설정입니다:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/error").permitAll() // /error 엔드포인트 접근 허용
.anyRequest().authenticated();
}
수정 후, 다양한 에러 상황을 재현하며 설정 변경이 제대로 작동하는지 검증했습니다. 이제 각 에러 상황에서 적절한 상태 코드와 메시지가 반환되기 시작했습니다.
최종적으로, 문제의 원인이 DispatcherServlet의 응답 플로우와 Spring Security 설정의 미비점에 있었음을 명확히 파악할 수 있었습니다. /error 엔드포인트에 대한 접근 허용 설정을 추가함으로써 문제를 해결했고, 이를 통해 에러 상황에서도 디버깅과 문제 해결이 원활해졌습니다.