Spring Security JWTFilter에서 Exception 처리하기
2024. 7. 28. 16:36ㆍSpring
JWT 토큰 로그인을 구현하다가, JWT Filter에서 토큰 관련하여 잘못된 요청이 들어오면
CustomException을 던지는 방식으로 코드를 작성했는데 아무리해도 Exception 처리가 안되는 것 같았다.
찾아보니 Spring Security 에서는 기존에 사용하던 Custom Exception 을 처리하지 못한다고 한다.
그 이유는
Filter는 Dispatcher Servlet보다 앞단에 존재하고 Handler Interceptor는 뒷단에 존재하기 때문에
Filter에서 보낸 예외는 Exception Handler로 처리를 못한다.
-> 설정을 따로 해줘야 한다 !
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http
.cors(corsCustomizer -> corsCustomizer.configurationSource(new CorsConfigurationSource() {
@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:5173", "http://localhost:3000"));
configuration.setAllowedMethods(Collections.singletonList("*"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Collections.singletonList("*"));
configuration.setMaxAge(3600L);
configuration.setExposedHeaders(Collections.singletonList("Set-Cookie"));
configuration.setExposedHeaders(Collections.singletonList("access"));
return configuration;
}
}));
// 예외 처리 설정
http.exceptionHandling(exceptionHandling -> exceptionHandling
.authenticationEntryPoint(customAuthenticationEntryPoint)
.accessDeniedHandler(customAccessDeniedHandler)
);
SecurityConfig 파일에서 http.exceptionHandling 을 사용하여 exception을 handling 해주면 된다.
위와 같이 코드를 적어주고,
AuthenticationEntryPoint를 implement한 CustomAuthenticationEntryPoint 클래스를 작성해준다.
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
ApiResponse<Object> responseBody = ApiResponse.error(UNAUTHORIZED, "만료되었거나 잘못된 토큰입니다. 토큰을 확인해주세요.");
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write(new ObjectMapper().writeValueAsString(responseBody));
}
}
그리고 AccessDeniedHandler를 implement 한 CustomAccessDeniedHandler 클래스도 작성해준다.
@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
ApiResponse<Object> responseBody = ApiResponse.error(UNAUTHORIZED, "만료되었거나 잘못된 토큰입니다. 토큰을 확인해주세요.");
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getWriter().write(new ObjectMapper().writeValueAsString(responseBody));
}
}
참고 :
'Spring' 카테고리의 다른 글
Entity 클래스에서 자주 사용하는 어노테이션 (1) | 2024.09.08 |
---|---|
스프링 3 이상 Multipart Config 설정 (0) | 2024.07.30 |
@EnableWebMvc와 WebMvcConfigurer (0) | 2024.06.25 |