Spring Boot · 2026-02-26

Spring Boot에서 CORS 설정과 보안 고려사항

Spring Boot에서 CORS의 개념부터 Controller·전역 설정, Spring Security 연동 시 발생하는 문제와 해결 방법, 보안 고려사항 설명

작성일 : 2026-02-26 ㆍ 작성자 : 관리자
post
목차

들어가며

CORS(Cross-Origin Resource Sharing)는 브라우저가 다른 출처의 리소스에 접근할 때 적용하는 보안 정책이다. API 서버를 개발할 때 클라이언트와 서버의 출처가 다르면 브라우저가 요청을 차단할 수 있다. 본문에서는 Spring Boot에서 CORS를 이해하고 설정하는 방법, Spring Security와 함께 사용할 때의 주의점, 실제로 자주 만나는 에러와 해결책을 다룬다.

CORS 기본 개념

CORS는 응답에 특정 헤더를 추가해 브라우저에게 허용 여부를 알린다. 기본 흐름은 다음과 같다.

  • 단순 요청(simple request): 브라우저가 실제 요청을 바로 보낸다.
  • 프리플라이트(preflight): 안전하지 않은 메서드나 커스텀 헤더가 있을 때 브라우저가 OPTIONS 요청을 먼저 보낸다.

주요 헤더로는 Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials 등이 있다.

Spring Boot에서의 기본 설정

간단한 API라면 Controller 레벨에서 @CrossOrigin을 사용해 원하는 출처를 허용할 수 있다. 프로젝트가 작거나 특정 엔드포인트만 허용할 때 편리하다.

Controller 레벨 예시

@RestController
@RequestMapping("/api")
public class ApiController {

  @CrossOrigin(origins = "https://example.com")
  @GetMapping("/data")
  public ResponseEntity<String> getData() {
    return ResponseEntity.ok("hello");
  }
}

이 방식은 빠르지만 여러 컨트롤러에 반복 적용하면 관리가 번거로워진다.

전역 CORS 설정

애플리케이션 전역에서 일괄 설정하려면 WebMvcConfigurer를 구현해 CORS 매핑을 등록한다. 이렇게 하면 모든 컨트롤러에 일관된 규칙을 적용할 수 있다.

WebMvcConfigurer 예시

@Configuration
public class WebConfig implements WebMvcConfigurer {

  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
      .allowedOrigins("https://example.com")
      .allowedMethods("GET", "POST", "PUT", "DELETE")
      .allowedHeaders("*")
      .allowCredentials(true);
  }
}

Spring Security와 함께하는 CORS 설정

Spring Security를 사용하는 경우 CORS 설정을 Security 필터 체인에서 활성화해야 한다. 그렇지 않으면 Spring Security가 CORS preflight 요청을 차단해 브라우저에서 에러가 발생한다.

Spring Security 연동 예시

다음은 CorsConfigurationSource를 빈으로 등록하고 Security 설정에서 cors()를 호출하는 방식이다.

@Configuration
public class SecurityConfig {

  @Bean
  public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowedOrigins(Arrays.asList("https://example.com"));
    config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
    config.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
    config.setAllowCredentials(true);

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

  @Bean
  public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.cors().and()
      .csrf().disable()
      .authorizeRequests().anyRequest().authenticated();
    return http.build();
  }
}

중요한 점은 WebMvcConfigurer의 전역 설정만으로는 충분하지 않을 수 있다는 것이다. Security 필터가 우선 적용되므로 Security 설정에서도 cors 허용을 명시해야 한다.

자주 발생하는 에러와 해결

  • Access-Control-Allow-Origin 없음: 서버 응답에 해당 헤더가 없다면 브라우저가 차단한다. 전역 설정 또는 Controller에서 헤더를 추가한다.
  • 프리플라이트 실패(OPTIONS 403 또는 404): Spring Security가 OPTIONS 요청을 허용하지 않으면 발생한다. Security에서 cors() 활성화 및 허용 메서드에 OPTIONS를 포함한다.
  • Credentials 관련 문제: allowCredentials(true)일 때 Access-Control-Allow-Origin에 와일드카드("*")를 사용할 수 없다. 명시적 출처를 설정해야 한다.

보안 고려사항

CORS는 편의성과 보안의 균형을 요구한다. 무분별한 허용은 공격 표면을 넓힌다. 다음 항목을 검토한다.

  • 허용 출처는 최소화: 신뢰할 수 있는 도메인만 등록한다.
  • 자격증명 처리: 쿠키나 Authorization 헤더를 사용하면 allowCredentials(true)와 특정 출처 설정이 필요하다.
  • 허용 헤더와 메서드 제한: 필요한 헤더·메서드만 허용해 공격 가능성을 줄인다.
  • 프리플라이트 로깅: 의심스러운 출처나 빈번한 프리플라이트를 모니터링한다.

구현 체크리스트

  • Controller 수준의 @CrossOrigin으로 빠르게 테스트
  • 운영 환경에서는 전역 설정(WebMvcConfigurer)으로 통일
  • Spring Security 사용 시 corsConfigurationSource 빈과 http.cors() 호출 추가
  • Credentials 사용 시 와일드카드 출처 사용 금지
  • 필요한 메서드·헤더만 허용

마무리

Spring Boot에서 CORS를 올바르게 설정하면 클라이언트와 서버 간의 통신이 원활해진다. 특히 Spring Security와 함께 사용할 때는 필터 체인에서 CORS가 처리되는지 반드시 확인해야 한다. 설정은 간단하지만 보안 측면을 고려해 출처와 자격증명 정책을 신중히 설계하는 것이 중요하다.

spring boot cors 설정 cors spring security 설정 spring boot cors 에러 해결 Spring Boot CORS 설정 Spring Security 프리플라이트 Access-Control-Allow-Origin