본문 바로가기

Web/spring

[Spring framework Web MVC docs] 1.7. CORS

728x90

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-cors

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, "Spring Web MVC," comes from the name of its source module (spring-webmvc), but it is more commonl

docs.spring.io

 

틀린 해석이나 내용은 알려주시면 수정하겠습니다, 감사합니다 😉

 


1.7. CORS

 

Spring MVC lets you handle CORS (Cross-Origin Resource Sharing

 

Cross-Origin Resource Sharing (CORS)??

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

 

Cross-Origin Resource Sharing (CORS) - HTTP | MDN

Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS also relies on a mechanism by which

developer.mozilla.org

 

 

 

 

1.7.1. Introduction

보안상의 이유로 브라우저는 현재 출처 외부의 리소스에 대한 AJAX 호출은 금지하고 있다
a.com 스크립트는 자격증명으로 b API에 AJAX를 요청할 수 없어야한다
 
CORS는 대부분의 브라우저에서 구현되는 W3C specification 이다
 
 
 

1.7.2. Processing

CORS specification은  preflight, simple, and 실 request 를 구분한다.

 

Spring MVC HandlerMapping 은 CORS에 대한 내장 지원을 제공하고 있다다.

request를 handler에 성공적으로 매핑한 후 HandlerMapping implementations 는 given request 및 handler에 대한 CORS 구성을 확인하고 추가 작업을 진행한다. preflight 요청은 직접 처리되는 반면 단순 및 실제 CORS 요청은 가로채고 검증되며 필수 CORS 응답 헤더 세트가 있다.  원본 간 요청을 활성화하려면(Origin 헤더가 있는데 요청 호스트와 다른 경우) 명시적으로 선언된 일부 CORS 구성이 있어야 한다. 일치하는 CORS 구성이 없으면 preflight 요청은 거부된다. 단순한 CORS 요청의 응답에 CORS 헤더가 추가되지 않으므로 브라우저에서 거부하게 된다.

 

각 HandlerMapping은 URL 패턴 기반 CorsConfiguration 매핑으로 각각 구성이 가능하다.

대부분의 경우 애플리케이션은 MVC Java 구성 또는 XML 네임스페이스를 사용하여 이러한 매핑을 선언하므로 single global map이 모든 HandlerMapping 인스턴스에 전달된다.  HandlerMapping 수준에서 전역 CORS 구성을 보다 세분화된 처리기 수준 CORS 구성과 결합할 수 있다.

예를 들어 애노테이션이 달린 컨트롤러는 클래스 또는 메서드 수준의 @CrossOrigin 주석을 사용할 수 있다(다른 handlers는 CorsConfigurationSource를 구현할 수 있음).

전역 구성과 로컬 구성을 결합하는 규칙은 일반적으로 추가적이다.

예를 들어 모든 전역 및 로컬 원본이 있을 때, 단일 값만 허용될 수 있는 속성의 경우, (allowCredentials 및 maxAge) local 이 전역 값을 재정의한다.

CorsConfiguration

https://docs.spring.io/spring-framework/docs/6.0.4/javadoc-api/org/springframework/web/cors/CorsConfiguration.html#combine-org.springframework.web.cors.CorsConfiguration-

 

  • CorsConfiguration
  • CorsProcessor,DefaultCorsProcessor
  • AbstractHandlerMapping

 

 

1.7.3. @CrossOrigin

 

@CrossOrigin 애노테이션은 주석이 달린 메서드에서 원본 간 request 를 활성화한다

 

@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin
    @GetMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @DeleteMapping("/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

 

By default, @CrossOrigin allows:

  • All origins.
  • All headers.
  • All HTTP methods to which the controller method is mapped.

 

allowCredentials는 민감한 user-specific information(cookie 및 CSRF token)을 노출하는 신뢰 수준을 설정하고 적절한 경우에만 사용해야 하기 때문에 기본적으로 비활성화 되어있다. 활성화시킬 경우 allowOrigins를 하나 이상의 특정 도메인(특수 값 "*" 제외)으로 설정하거나 allowOriginPatterns 속성을 사용하여 동적 원본 집합과 일치시킨다.  

 

maxAge는 30분으로 설정되어있다.

@CrossOrigin 애노테이션은 클래스 수준에서도 지원이 가능하다

 

@CrossOrigin(origins = "https://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @GetMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @DeleteMapping("/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

    @CrossOrigin("https://domain2.com")
    @GetMapping("/{id}")
    public Account retrieve(@PathVariable Long id) {
        // ...
    }

    @DeleteMapping("/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

 

 

1.7.4. Global Configuration

세분화된 컨트롤러 메서드 수준 구성 외에도 일부 전역 CORS 구성도 정의하려고 할 수 있다. 어떤 HandlerMapping에서든 URL 기반 CorsConfiguration 매핑을 개별적으로 설정할 수 있습니다. 그러나 대부분의 애플리케이션은 MVC Java 구성 또는 MVC XML 네임스페이스를 사용하여 이를 수행한다

 

By default, global configuration enables the following:

  • All origins.
  • All headers.
  • GET, HEAD, and POST methods.

 

allowCredentials는 민감한 user-specific information(cookie 및 CSRF token)을 노출하는 신뢰 수준을 설정하고 적절한 경우에만 사용해야 하기 때문에 기본적으로 비활성화 되어있다. 활성화시킬 경우 allowOrigins를 하나 이상의 특정 도메인(특수 값 "*" 제외)으로 설정하거나 allowOriginPatterns 속성을 사용하여 동적 원본 집합과 일치시킨다.  

 

maxAge는 30분으로 설정되어있다.

 

 

 

Java Configuration

- Java 에서 CORS 활성화

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("/api/**")
            .allowedOrigins("https://domain2.com")
            .allowedMethods("PUT", "DELETE")
            .allowedHeaders("header1", "header2", "header3")
            .exposedHeaders("header1", "header2")
            .allowCredentials(true).maxAge(3600);

        // Add more mappings...
    }
}

 

 

XML Configuration

- xml 에서 CORS 활성화

 

<mvc:cors>

    <mvc:mapping path="/api/**"
        allowed-origins="https://domain1.com, https://domain2.com"
        allowed-methods="GET, PUT"
        allowed-headers="header1, header2, header3"
        exposed-headers="header1, header2" allow-credentials="true"
        max-age="123" />

    <mvc:mapping path="/resources/**"
        allowed-origins="https://domain1.com" />

</mvc:cors>

 

 

 

1.7.5. CORS Filter

내장된 CorsFilter 을 이용해 CORS 지원을 적용할 수 있다

 

Spring Security 와 함께 쓸 경우

https://docs.spring.io/spring-security/reference/servlet/integrations/cors.html

 

 

 

CorsConfigurationSource 

CorsConfiguration config = new CorsConfiguration();

// Possibly...
// config.applyPermitDefaultValues()

config.setAllowCredentials(true);
config.addAllowedOrigin("https://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);

CorsFilter filter = new CorsFilter(source);

 

728x90