[패스트캠퍼스X야놀자 : 미니 프로젝트] Spring Security에서 CORS 설정하기

꼬마요리사레미·2023년 12월 18일

💡 Origin : Protocol + Host + Port

  • 같은 프로토콜 및 호스트 및 포트를 사용할 경우, 그 뒤의 요소는 다르더라도 같은 출처로 인정. (ex: https://www.domain.com:3000)
  • 위의 세가지 중 하나라도 출처와 다를 경우, 브라우저는 접속을 차단. ( 출처 비교 및 차단은 브라우저에서. 즉, 서버가 아닌 브라우저에 구현된 스펙. )
  • 모두 차단할 수 없기 때문에 몇 가지 예외 조항을 두고, 다른 출처의 요청이라도 허용할 수 있도록 설정. 그 중 하나가 CORS 정책을 지킨 요청.
    ( 즉, SOP 정책을 위반 해도, CORS 정책에 따르면 다른 출처의 요청도 허용 )
SOP(Same Origin Policy) : 동일한 출처에 대한 정책.  동일한 출처에서만 리소스를 공유 가능.

💡 Cross-Origin Resource Sharing : 교차 출처 리소스 공유

  • 클라이언트가 보내준 Origin : 출처
  • 서버가 보내준 Access-Control-Allow-Origin : 접근 허용된 출처 URL
  • 브라우저에서 비교를 통해 유효 하지 않다면, 서버가 전송한 응답을 클라이언트에게 전달 하지 않고 버림.
  • 즉, 서버에서 Access-Control-Allow-Origin 헤더에 허용할 출처를 기재해서 클라이언트에 응답.

💡 Preflight Request : 예비 요청

  • 브라우저는 요청을 보낼 때 바로 보내지 않고, 예비 요청을 보내 서버와 잘 통신 되는지 확인 후 본 요청을 보냄.
  • 즉, 예비 요청의 역할은 본 요청을 보내기 전에 브라우저가 안전한 요청인지 확인 하는 것.
  • 예비 요청의 HTTP Method 는 GET 요청 및 POST 요청이 아닌, OPTIONS 요청이 사용 된다는 것이 특징.
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .cors().configurationSource(corsConfigurationSource()); // CORS 구성을 위한 설정 소스 지정
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();

        // 클라이언트에서 preflight 요청 결과를 저장할 기간을 지정.
        // 3600초 동안 preflight 요청을 캐시하는 설정으로, 첫 요청 이후 60초 동안은 OPTIONS 메소드를 사용하는 예비 요청을 보내지 않음.
        configuration.setMaxAge(MAX_AGE_TIME);

        // 요청을 허용하는 헤더.
        configuration.addAllowedOriginPattern("*");

        // 요청을 허용하는 메서드.
        configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));

        // 요청을 허용하는 헤더.
        configuration.addAllowedHeader("*");

        // Authorization Header 를 브라우저에 노출 시켜서, 클라이언트에서 JavaScript 로 읽을 수 있도록 허용.
        // 인증 정보를 담고 있어 보안에 취약할 수 있기 때문에, Access Token 의 경우 유효 기간을 짧게 설정.
        configuration.addExposedHeader(AUTHORIZATION_HEADER);

        // 클라이언트 요청이 Cookie 및 Authorization Header Token 통해, 자격 증명을 해야 하는 경우 true 설정.
        // 자바스크립트 요청에서 withCredentials : true 설정 시, 해당 요청에 대한 응답을 해줄 수 있는지 나타냄.
        configuration.setAllowCredentials(true);

        // 모든 경로에 대해 위에 정의한 CORS 구성을 등록.
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);

        return source;
    }
}
  • 특정 경로에 대해 CorsConfiguration 객체에서 설정한 값을 CorsConfigurationSource 인터페이스를 구현한 UrlBasedCorsConfigurationSource에 적용시킨다. 여기서는 모든 경로로 설정되어 있다.
  • Spring Security의 CORS 설정에서는 CorsConfigurationSource 인터페이스의 구현체를 파라미터로 받는 configurationSource가 있다. 여기에 설정한 UrlBasedCorsConfigurationSource 객체를 넣어주면 위에서 설정한 내용이 Spring Security에 적용된다.

0개의 댓글