Spring Security - CORS

TopOfTheHead·2025년 11월 18일

Spring Security

목록 보기
11/21

CORS ( Cross-Origin Resource Sharing ) :
브라우저Cross-Origin Request의 허용여부를 결정하는 웹 보안정책.
CORS가 존재하지 않으면, 브라우저가 Cross-Origin Request를 무조건 차단.

서버 - 서버 간 통신, Postman - 서버간 통신에는 적용되지 않으나, 브라우저 간 통신CORS 정책이 적용
브라우저Spring이 통신 시 CORS 정책을 허용하는 코드를 정의

Spring BootSpring Security에서는 기본적으로 모든 다른 Origin로부터의 HTTP Request로 인한 API 호출( Cross-Origin Request )은 차단하도록 설정되어있음.
▶ 백엔드 API 서버 ( = Spring Application )에서 CORS Configuration을 통해 Access-Control-Allow-Origin Header를 정의하여 모든 도메인 또는 특정 도메인에만 HTTP Request를 허용하도록 설정.

ex ) http://localhost:3000/ ( React )에서 http://localhost:8080/ ( Spring )으로 다른 Origin으로부터 HTTP Request를 통해 REST API를 호출하는것이므로, CORS로 인한 Spring Security에 의해 차단.

  • Cross-Origin Request :
    。특정 Origin에서 다른 Origin으로 HTTP Request를 전송하는것을 의미.

    Origin :
    。웹브라우저에서 Origin프로토콜 + 도메인 + 포트번호 를 조합한 값.
    https:// + example.com + :8080

CORS Configuration 종류
Spring MVC 활용 시 Cross-Origin Request 허용하는 기법

  • Global Configuration :
    。모든 Controller , REST ControllerCross-Origin Request를 허용하도록 설정.
    CORS ConfigurationWebMvcConfigurer의 instance를 Spring Bean으로 반환하는 @Bean Method 구현.
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class BasicAuthSecurityConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            // addCorsMappings()를 Override하여 작성하며
            // 매개변수로 전달된 CorsRegistry instance를 통해 Cross-Origin Request의 CORS Configuration 수행.
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**") // 모든 URL Pattern에 대하여 CORS 허용.
                        .allowedMethods("*") // 모든 HTTP Method에 대하여 CORS 허용
                        .allowedOrigins("http://localhost:3000"); // ReactOrigin에 대해서만 CORS 허용.
            }
        };
    }
 }
  • @Configuration이 선언된 Configuration Class에서 WebMvcConfigurer @Bean Method 생성.
    SecurityFilterChain Configuration @Bean MethodConfiguration Class에서 생성하는 것과 동일하게 Configuration Class에 생성.
    WebMvcConfigurer의 instance를 생성하여 return하면서 해당 instance에 addCorsMappings()Override하여 구현.
    ▶ Override를 수행할 addCorsMappings(CorsRegistry registry)에서 CorsRegistry객체를 활용하여 CORS Configuration을 수행 후 WebMvcConfigurer instanceSpring Bean으로 반환.

    • WebMvcConfigurer
      Spring MVC의 세부적인 JAVA 기반 Configuration을 사용자 정의하는 구현 Method를 제공하는 Interface.
      Spring Boot은 기본적으로 Auto Configuration을 제공하지만, 세부설정이 필요할 경우 WebMvcConfigurer을 통해 정의.

      。 해당 Interface를 구현하여 CORS Configuration , Interceptor 추가 , Static Resource Mapping , View Controller Configuration 수행하는 구현 Method를 구현.

      WebMvcConfigurer 구현 메소드

    • addCorsMappings(CorsRegistry registry)
      Spring에서 CORS 정책을 설정하는 WebMvcConfigurer interface 구현 Method.
      ▶ 해당 Method를 구현하여 활용 시, Back-end Application에서 특정 OriginCross-Origin Request를 전역적으로 허용가능.

      CorsRegistry의 instance를 매개변수로 가져오므로, 해당 CorsRegistry객체를 이용해 CorsRegistry의 Method를 활용하여 CORS정책을 설정.
  • CorsRegistry :
    Spring MVC에서 CORS정책을 설정 시 사용하는 Class.
    WebMvcConfigurer InterfaceaddCorsMappings(CorsRegistry registry) 구현 Method를 통해 활용됨.

    CorsRegistry Method

    • CorsRegistry객체.addMapping("/URLpattern")
      Spring Boot에서 Cross-Origin RequestCORS를 허용할 URL 패턴을 지정.

      CorsRegistry객체.addMapping("/api/**") :
      /api/ 로 시작하는 모든 Cross-Origin Request에 대하여 CORS 허용.
      CorsRegistry객체.addMapping("/**") :
      。모든 Cross-Origin Request에 대하여 CORS 허용.

    • CorsRegistry객체.allowedOrigins("Origin1", "Origin2" , ...)
      Spring Boot에서 CORS를 허용할 Origin을 지정하는 Method.

      CorsRegistry객체.allowedOrigins("http://localhost:3000")
      。특정 Origin에 대해서만 CORS 허용.
      CorsRegistry객체.allowedOrigins("*")
      。모든 Origin에 대해서 CORS 허용.

    • CorsRegistry객체.allowedMethods("GET", "POST" , ...)
      Cross-Origin Request에서 CORS를 허용할 HTTP Method 지정.
      "GET" , "POST" , "PUT" , "DELETE" , "PATCH"

    • CorsRegistry객체.allowedHeaders("Content-Type" , "Authorization" , ...)
      Spring Boot에서 CORS를 허용할 Header를 지정하는 Method.
      CorsRegistry객체.allowedHeaders("*") : 모든 header에 대해서 CORS 허용.

    • CorsRegistry객체.allowCredentials(Boolean)
      Cookie, Authorization Header등의 인증정보를 포함한 Cross-Origin Request에 대하여 CORS 허용여부 설정.
      CorsRegistry객체.allowCredentials(true) 설정 시 CorsRegistry객체.allowedOrigins("*")를 사용할 수 없으며, 반드시 특정 Origin만 지정하여 설정해야한다.


    • Preflight Request :
      。브라우저가 CORS Policy에 따라 Server에 실제 HTTP Request를 전달하기 전 사전에 확인용도로 OPTIONS Request Method를 사용하여 전달하는 Request.
      Preflight RequestCORS Policy가 적용될때, 특정 조건을 만족 시 자동으로 발생.
      Preflight Request 발생 조건
      。다음 조건을 만족하는 경우 Preflight Request 발생.
    • Cross-Origin :
      。다른 URL의 출처( Origin )으로 요청 시 발생.

    • Simple Request에 해당하지 않는 경우.
      PUT , DELETE 등의 HTTP Method 또는 Authorization Header를 포함 시 Preflight Request 발생.

      Simple Request :
      。。GET, HEAD , POSTHTTP Method만 사용.
      Content-Typeapplication/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나
      。Custom Header ( Authorization , X-Custom-Header )가 없는 경우


    • OPTIONS Request Method
      Server의 특정 Resource에서 허용하는 HTTP Method를 물어보는 용도의 Request.
      Client에서 해당 resource URL에서 사용할 수 있는 HTTP Method가 무엇인지 묻는 용도로 활용됨.


    • Local Configuration :
      。특정 Controller , REST Controller@CrossOrigin을 선언하여 Cross Origin Request를 허용설정.
      Global Configuration와 달리 특정 Controller에만 국한.
      @CrossOrigin
      Spring Framework에서 CORS를 허용하는 용도의 Annotation으로 origins를 통해 정의된 도메인으로부터의 Cross-Origin Request의 허용여부를 결정.
      @Controller , @RestController가 선언된 Class 앞에 정의하여 origins 속성에 의해 허용된 도메인으로부터 해당 ControllerAPI호출CORS를 허용.

      origins="URL" 속성을 통해서 Cross-Origin Request를 허용할 특정 도메인을 지정.
      origins 속성을 지정하지 않는 경우 모든 도메인으로부터의 Cross-Origin Request를 허용.
    import org.springframework.web.bind.annotation.*;
    import java.util.List;
    @RestController
                // Controller Class에 Cross Origin 선언.
    @CrossOrigin(origins="http://localhost:3000")
    public class Security_Filter_Chain {
        @GetMapping(path="/todos")
        public List<Todo> returnTodos(){
            return TODOS;
        }
    }
profile
공부기록 블로그

0개의 댓글