Spring Security 사용시 Cors 처리
CORS란?
CORS(Cross-Origin Resource Sharing)는 웹 페이지 상의 제한된 리소스를 최초 자원이 서비스된 도메인 밖의 다른 도메인으로부터 요청할 수 있게 허용하는 구조입니다.
기본적으로 HTTP request는 Cross-Site HTTP Requests가 가능합니다. 그러나 보안상의 이유로 브라우저에서는 Same Origin Policy를 적용 받기 때문에 요청이 불가합니다. 즉, 프로토콜, 호스트명, 포트가 같아야만 요청이 가능합니다.
최근 프로젝트를 진행하면서 Back End 서버를 구성하고 REST API를 구성하여 Front End 개발자분께 제공하였습니다.
처음 프로젝트를 구성할때 WebMvcConfigurer를 임플리먼트하여 클래스를 생성하고 @Configuration 어노테이션을 선언하였습니다. 이 안에는 addCorsMappings을 재정의하여 Cors관련하여 처리를 미리하였습니다. 이후 postman과 내부에서 테스트를 진행하였을때 문제없다고 판단하고, 개발서버에 배포한 후 Front End 개발자분께 테스트 요청을 드렸습니다. 그러나 이때 Cors 허용 관련 문제가 발생하였습니다. 처음에는 Cors 설정을 했음에도 불구하고 왜 이런 문제가 발생하는지 이해하지 못했습니다. 그러다가 구글링을 통해 아래와 같은 답을 얻었습니다.
참조 사이트부터 먼저 링크 걸겠습니다.
https://stackoverflow.com/questions/40418441/spring-security-cors-filter/43559288#43559288
Spring security CORS Filter
We added Spring Security to our existing project. From this moment on we get a 401 No 'Access-Control-Allow-Origin' header is present on the requested resource error from the our server. That's bec...
stackoverflow.com
https://toycoms.tistory.com/37
Spring Security CORS
CORS란? - HTTP 요청은 기본적으로 Cross-Site HTTP Requests가 가능합니다. Simple 하게 다른 도메인의 Resource를 사용하는것을 말합니다. 하지만 Cross-Site HTTP Requests는 Same Origin Policy를 적용 받기 때문에 요청
toycoms.tistory.com
결론을 말하자면, 진행되고 있는 프로젝트는 Spring Security가 적용된 프로젝트입니다. Spring Security가 적용되었을시에는 Cors설정과 관련하여 HttpSecurity 설정 부분에서 cors().configurationSource(corsConfigurationSource())을 등록해줘야합니다.
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedOrigin("*");
configuration.addAllowedHeader("*");
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().authenticated()
.and()
.headers()
.cacheControl()
.and()
.contentTypeOptions()
.and()
.httpStrictTransportSecurity()
.includeSubDomains(true)
.maxAgeInSeconds(31536000)
.and()
.frameOptions().deny()
.xssProtection().block(false)
.and().and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(new RestUserAuthenticationEntryPoint())
.accessDeniedHandler(new RestAccessDeniedHandler())
.and()
.csrf().disable()
.formLogin().disable()
.cors().configurationSource(corsConfigurationSource());
JwtAuthenticationApiFilter jwtAuthFilter = new JwtAuthenticationApiFilter(jwtTokenProvider);
http.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
또한, addCorsMappings를 재정의한 내용도 유지하여야 저는 Cors 관련 이슈 부분을 해결 할 수 있었습니다.
Cors 관련해서는 항상 어려우면서도 또 이렇게 간단하게 해결이 되어서 정말 다행입니다.