개발/Project

Spring Security에서 CORS 설정하기

라니킴 2023. 1. 19. 20:59

브라우저는 보안상의 이유로 다른 출처의 리소스를 사용하는 것을 기본적으로 제한하고 있다.

다른 출처의 리소스를 불러오려면 접근할 수 있는 권한을 달라고 브라우저에게 요청을 해야한다.

 

이번 프로젝트 중 프론트엔드 서버에서 백엔드 서버에 접근하니 아래와 같은 요청이 떴다.

CORS 정책에 의해서 다른 출처의 서버에 접속하는 것이 막혔다고 브라우저에서 에러를 발생시켜준 것이다.

권한 요청을 Http header에 담아보내 접근할 수 있는 권한을 부여하도록 브라우저에게 알려주어야 한다.

 

백엔드에서 몇 가지 설정이 필요했다.

이번 프로젝트에서 Spring Security + JWT 를 사용했기 때문에 Client는 API 호출 시 모든 요청에 대해 Header의 Authorization에 JWT 토큰을 전송한다.

그래서 일반적인 요청이 아니라 브라우저에서 서버에 preflighted 요청을 보낸다.

 

* preflighted 요청
   1. options 메서드를 통해 다른 도메인의 리소스에 요청이 가능한지 확인한다.

   2. 요청이 가능하다면 실제 요청을 보낸다.

 

SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Override
	public void configure(HttpSecurity http) throws Exception {
		// http formLogin, headers .. 설정

		http.cors(); 
	
}

@Bean
	CorsConfigurationSource corsConfigurationSource() {

		CorsConfiguration configuration = new CorsConfiguration();
	
		config.setAllowCredentials(true);
     	config.addAllowedOrigin("*");
      	config.addAllowedHeader("*");
		config.addAllowedMethod("*");
		config.addExposedHeader("Authorization");
      
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		source.registerCorsConfiguration("/**", configuration);

		return source;
	}
}
  • http.cors()
    • Spring이 제공하는 CorsFilter를 등록하는 것과 같다.
    • 아래 코드와 같이 CorsConfig 만든 다음 filter를 추가하는 방법도 있다.
      @Configuration public class CorsConfig { 
      
      	@Bean public CorsFilter corsFilter() {
          
          	
              CorsConfiguration config = new CorsConfiguration();
              config.setAllowCredentials(true); config.addAllowedOrigin("*");
              config.addAllowedHeader("*");
              config.addAllowedMethod("*");
              
              UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
              source.registerCorsConfiguration("/api/**", config);
              
              return new CorsFilter(source);
              
              }
  • addAllowedOrigin("*")

     *로 해놓으면 모든 주소 허용한다는 의미이다. 나중에 프론트엔드 서버 ip 주소만 허용하도록 변경했다.

  • addAllowedHeader("*")

     허용되는 HTTP request headers 지정.

  • addAllowedMethod("*")

     허용하는 Method. *로 해놓으면 모든 method 허용한다는 의미.

  • setAllowCredentials(true)

     서버가 응답할 때 json을 자바스크립트에서 처리할 수 있도록 한다.

  • config.addExposedHeader("Authorization")

     token이 response로 노출되어야 하기 때문에 나열해주기.

     Authorization은 와일드 카드로 지정하지 않으므로 꼭 명시해줘야 한다.