[Spring Security] CORS

우잼·2023년 9월 18일
3
post-thumbnail

1. 들어가며


지난번엔 Spring Security를 통해 CSRF 설정하는 방법을 알아보았다. 이번엔 CORS 설정에 대해서 적어보려고 한다. CORS란 무엇이며 어떻게 설정해야할까?

2. CORS


2.1. CORS란?

  • Cross-Origin Resource Sharing로 교차 출처 리소스 공유
  • 서로 다른 Origin을 가진 Application이 서로의 Resource에 접근할 수 있도록 해줌

Origin

  • 프로토콜, 호스트, 포트 를 통틀어 Origin 이라고 함
  • 즉, 여기서 하나라도 다르면 Cross Origin이 됨
  • 보안상의 이유로 Cross Origin HTTP Request를 제한함

하지만 한 서버에서 데이터와 정적파일을 같이 렌더링해 사용자의 요청을 처리하는것이 아닌 api 서버를 분리하여 통신한다면 Cross-Origin 이므로 오류가 발생할 것이다.

2.2. CORS 설정하기

2.2.1 Annotation 이용하기

  • Controller 또는 메소드 단에서 annotation을 통해 적용하는 방법
    @CrossOrifin 어노테이션 사용
@RequestMapping("/somePath")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class SomeController {
}
  • @CrossOrgin이라는 어노테이션을 사용하여 원하는 메소드나 원하는
    mapping에만 사용할 수 있다.
  • origin: 도메인을 설정하면 해당 도메인은 다른 orgin을 요청을 받을 수 있음
  • allowedOrigin: 자원 공유를 허락할 모든 orgin을 지정할 수 있음
  • allowedMethods: 허용할 HTTP method를 지정할 수 있음
  • allowrdHeaders: 클라이언트 측의 CORS 요청에 허용하는 헤더를 지정
    -> 기본적으로 Content-Type, Accept 및 Origin과 같은 간단한 요청 헤더만 허용됨
  • 특정 메소드에만 적용할 수도 있다.
@RestController
@RequestMapping("/somePath")
public class SomeController {

    @CrossOrigin(origins="*")
    @RequestMapping(value = "/{something}",method = RequestMethod.DELETE)
    public ResponseEntity<String> delete(@PathVariable Long reservationNo) throws Exception{
    }

}

2.2.2 Configuration으로 설정

  • 다음 방법은 Global하게 적용하는 방법
  • 작업중인 project 위치에 config 패키지를 생성하고 WebConfig 클래스를 생성
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
    public void addCorsMappings(CorsRegistry registry) {
    }
}
  • @Configuration을 통해 설정파일이라는 것을 명시
  • WebMvcConfigurer을 implements
  • addCorsMappings 메소드를 오버라이드
registry.addMapping("/**");
  • 다음 코드를 추가하면 CORS를 적용할 URL 패턴을 정의할 수 있음
  • Default
    • Allow all origins.
    • Allow "simple" methods GET, HEAD and POST.
    • Allow all headers.
    • Set max age to 1800 seconds (30 minutes).
.allowedOrigins("*");
  • allowedOrigins 메소드를 이용해 자원 공유를 허락할 Origin 지정
.allowedOrigins("http://localhost:8080", "http://localhost:8081");
  • 다음과 같이 여러개의 orgin을 한번에 설정 가능
.allowedMethods("GET", "POST");
  • 허용할 HTTP method 지정, 마찬가지로 여러개를 지정할 수 있으며 * 를통해 모든 method 허용 가능
.maxAge(3000);
  • 원하는 시간만큼 pre-flight 리퀘스트를 캐싱할 수 있음
.allowCredentials(true)
  • 클라이언트 측에 대한 응답에 쿠키, 인증 헤더를 포함할 수 있는지 여부 지정
  • 기본값은 false, true로 지정시 클라이언트가 요청에 credentials를 포함하고 응답에서 받을 수 있음

최종 코드를 살펴보면 아래와 같다.

public class WebConfig implements WebMvcConfigurer {
   
    @Override
    public void addCorsMappings(CorsRegistry registry) {
       registry.addMapping("/**")
               ..allowedOrigins("*")
               .allowedMethods("*")
               .allowedHeaders("*")
               .allowCredentials(true)
               .maxAge(3600);
    }
}

2.1 오류

java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*"since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.

해당 오류는 스프링 부트에서 CORS 설정 시, allowCredentials(true)allowedOrigins("*")를 동시에 사용할 수 없도록 업데이트 되었다.

따라서 allowedOrigins("*")allowedOriginPatterns("*") 로 변경하면 된다.

💡 SecurityFilterChain 메소드에서 cors 설정을 disable 해줘야 한다.
기존엔 .cors().dsiable()로 하였지만 SpringBoot 3.1 이후론 csrf 을 disable 했을때 처럼 cors(AbstractHttpConfigurer::disable)라고 해줘야한다.

3. 최종 코드


  • WebConfig.java
@Configuration
public class WebConfig implements WebMvcConfigurer {
    /**
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
       registry.addMapping("/**")
               .allowedOriginPatterns("*")
               .allowedMethods("*")
               .allowedHeaders("*")
               .allowCredentials(true)
               .maxAge(3600);
    }
}
  • AuthenticationConfig.java
@Configuration
@EnableWebSecurity
public class AuthenticationConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
                .httpBasic(HttpBasicConfigurer::disable)
                .csrf(AbstractHttpConfigurer::disable)
                .cors(AbstractHttpConfigurer::disable);
        return httpSecurity.build();
    }
}

해당 글은 CORSCSRF에 대한 모든 설정을 허용한 경우이다. 사이드 프로젝트나 단순히 테스트, 공부를 위한 경우라면 해당 설정을 적용해도 문제는 없다.

하지만 만약 실제로 서버 배포를 진행한다면 해당 설정을 절대로 그대로 사용하지 말고 각자의 서버 환경에 맞게 변경해주어야 한다.

4. Reference


Spring Security Cors
[Spring Boot] CORS Filter 설정하기 (CORS 오류 해결방법) - Java
[Spring Boot] CORS 설정하기
[Tistory] Spring Boot Cors 설정하기
[Spring Boot] CORS 설정 시 addCorsMappings 관련 에러

profile
나는 재민

0개의 댓글

관련 채용 정보