Spring Security Cors 에러( WebMvcConfigurer/ corsConfigurationSource )
해당 포스팅을 이해하기 위한 정보
문제의 시작 No content to map due to end-of-input
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:4000")
.allowedMethods("GET","POST","PUT","DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.exposedHeaders(JwtUtil.AUTHORIZATION_HEADER);
}
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
log.info("로그인 시도");
try {
UserLoginDto requestDto = new ObjectMapper().readValue(request.getInputStream(), UserLoginDto.class);
System.out.println(requestDto);
....
위와 같이 WebMvcConfigurer를 구현해서 CORS를 다루면 Security filterChain에 UsernamePasswordAuthenticationFilter 에서 request.getInputStream()이 비어있는 상태가 되었다.
실제 네트워크를 확인해보면
서버에서 설정한 CORS 정책들이 preflight header에 적용되지 않았고 preflight 요청과 응답을 비교한 결과 안전하지 않아 Cors에러를 던졌다.
Security 공식 홈페이지를 찾아보자.
CORS must be processed before Spring Security, because the pre-flight request does not contain any cookies (that is, the JSESSIONID). If the request does not contain any cookies and Spring Security is first, the request determines that the user is not authenticated (since there are no cookies in the request) and rejects it.
CORS는 Security를 지나기 전에 먼저 처리되야 한다. 왜나면 쿠키나 데이터가 없는 preflight 요청을 받으면 자격이 없는 걸로 판단하고 거절되기 때문이다. Spring Security에선 Cors를 먼저 다룰 수 있는 쉬운 방법을 제공한다.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf((csrf) -> csrf.disable());
http.cors(withDefaults());
...
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:4000"));
configuration.setAllowedMethods(Arrays.asList("*"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setAllowCredentials(true);
configuration.addExposedHeader(JwtUtil.AUTHORIZATION_HEADER);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
위와 같이 SecurityFilterChain에서 cors(withDefaults()) 를 설정해주고 corsConfigurationSource 함수를 작성하면 Security에서 제공하는 Cors 처리를 할 수 있다.
WebMvcConfigurer를 지우고 Security에서 제공하는 Cors 처리를 사용하니 preflight response header에 설정한 Cors 정책이 보이고 본 요청도 Cors 에러를 던지지 않은 것을 확인할 수 있다.
'Spring > Security' 카테고리의 다른 글
Error) Spring Security @PreAuthorize/@Secured NPE (2) | 2024.10.15 |
---|---|
Spring Security Session 인증 - REST API login (1) | 2024.09.07 |
Spring Security 예외처리( AuthenticationEntryPoint, AccessDeniedHandler, unsuccessfulAuthentication ) (0) | 2023.07.26 |
스프링) Spring Security Authentication/Authorization (23-06-29) (0) | 2023.07.13 |