CORS ( Cross-Origin Resource Sharing ) :
。 브라우저가 Cross-Origin Request의 허용여부를 결정하는 웹 보안정책.
▶ CORS가 존재하지 않으면, 브라우저가 Cross-Origin Request를 무조건 차단.
。서버 - 서버 간 통신, Postman - 서버간 통신에는 적용되지 않으나, 브라우저 간 통신 시 CORS 정책이 적용
▶ 브라우저와 Spring이 통신 시 CORS 정책을 허용하는 코드를 정의
。 Spring Boot의 Spring 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 Controller에 Cross-Origin Request를 허용하도록 설정.
▶ CORS Configuration된 WebMvcConfigurer의 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() {
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("*") // 모든 HTTP Method에 대하여 CORS 허용
.allowedOrigins("http://localhost:3000"); // React의 Origin에 대해서만 CORS 허용.
}
};
}
}
@Configuration이 선언된 Configuration Class에서 WebMvcConfigurer @Bean Method 생성.
。SecurityFilterChain Configuration @Bean Method를 Configuration Class에서 생성하는 것과 동일하게 Configuration Class에 생성.
。 WebMvcConfigurer의 instance를 생성하여 return하면서 해당 instance에 addCorsMappings()를 Override하여 구현.
▶ Override를 수행할 addCorsMappings(CorsRegistry registry)에서 CorsRegistry객체를 활용하여 CORS Configuration을 수행 후 WebMvcConfigurer instance를 Spring 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에서 특정 Origin의 Cross-Origin Request를 전역적으로 허용가능.
。CorsRegistry의 instance를 매개변수로 가져오므로, 해당 CorsRegistry객체를 이용해 CorsRegistry의 Method를 활용하여 CORS정책을 설정.
CorsRegistry :
。Spring MVC에서 CORS정책을 설정 시 사용하는 Class.
▶ WebMvcConfigurer Interface의 addCorsMappings(CorsRegistry registry) 구현 Method를 통해 활용됨.
CorsRegistry Method
CorsRegistry객체.addMapping("/URLpattern")
。Spring Boot에서 Cross-Origin Request의 CORS를 허용할 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 Request는 CORS Policy가 적용될때, 특정 조건을 만족 시 자동으로 발생.
Preflight Request 발생 조건
。다음 조건을 만족하는 경우 Preflight Request 발생.
Cross-Origin :
。다른 URL의 출처( Origin )으로 요청 시 발생.
Simple Request에 해당하지 않는 경우.
。PUT , DELETE 등의 HTTP Method 또는 Authorization Header를 포함 시 Preflight Request 발생.
Simple Request :
。。GET, HEAD , POST의 HTTP Method만 사용.
。Content-Type이 application/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 속성에 의해 허용된 도메인으로부터 해당 Controller의 API호출 시 CORS를 허용.
。 origins="URL" 속성을 통해서 Cross-Origin Request를 허용할 특정 도메인을 지정.
▶ origins 속성을 지정하지 않는 경우 모든 도메인으로부터의 Cross-Origin Request를 허용.
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@CrossOrigin(origins="http://localhost:3000")
public class Security_Filter_Chain {
@GetMapping(path="/todos")
public List<Todo> returnTodos(){
return TODOS;
}
}