source

Spring Boot 2.0.x로 마이그레이션할 때 글로벌 CORS 구성이 중단됨

itover 2023. 7. 16. 20:26
반응형

Spring Boot 2.0.x로 마이그레이션할 때 글로벌 CORS 구성이 중단됨

Spring Boot 2.0.x(2.0.1)에서 'Access-Control-Allow-Credentials'가 비행 전 통화(OPTIONS)에 대한 응답으로 더 이상 전송되지 않는 이유는 무엇입니까?내 경우에는 해제)?다음은 스프링 부트 1.5.6에서 잘 작동하는 글로벌 CORS 구성입니다.

@Configuration
public class CorsConfig {

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins(
                        "http://localhost:3000",..)
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD");
        }
    };
}}

나의 폼 의존성(나는 나만의 보안을 수행하고 스프링 보안을 피하고 있습니다):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

REST 엔드포인트에 대한 서비스 호출이 사전 비행에 실패하는 경우:

http://localhost:8080/api/v5/sec/auth를 로드하지 못했습니다. 사전 비행 요청에 대한 응답이 액세스 제어 검사를 통과하지 못했습니다.응답에서 'Access-Control-Allow-Credentials' 헤더의 값은 '참'입니다. 요청의 자격 증명 모드가 '포함'인 경우 이 값은 '참'이어야 합니다.따라서 오리진 'http://localhost:3000'에 액세스할 수 없습니다.

Spring Boot 1.5.6의 경우 'Access-Control-Allow-Credentials' 헤더가 실제로 존재하고 Spring Boot 2.0.1에서 누락되었음을 확인했습니다.

WebMvcConfigurerAdapter가 지금은 더 이상 사용되지 않는 것처럼 보이지만, 여기에 있는 spring.io 의 최신 버전을 포함하여 찾을 수 있는 모든 설명서에는 글로벌 구성이 여전히 올바르다고 나와 있습니다.


업데이트:


마이그레이션 전후의 응답 헤더는 다음과 같습니다.

마이그레이션 전(Spring Boot 1.5.6):

액세스-제어-허용-자격 증명: true
액세스-제어-허용-원산지: http://localhost:3000
내용 유형: 응용 프로그램/json; 문자 집합=UTF-8
Date: Day, dd Monyyyyhh:mm:ss GMT
전송 인코딩: 청크됨
다양성: 원산지

마이그레이션 후(Spring Boot 2.0.1 - Access-Control-Allow-Credentials 헤더가 누락되었지만 다른 헤더는 변경/추가됨):

접근 제어-허용 헤더: 내용 유형
액세스-제어-허용-메소드: GET,HEAD,POST <-- 내가 지정한 메서드무시되었습니다.
액세스-제어-허용-원산지: * <-- 지정된 오리진무시되었습니다.
액세스 제어-최대 연령: 1800
내용 길이: 0
Date: Day, dd Monyyyyhh:mm:ss GMT
다양성: 원산지
다양성: 액세스-제어-요청-방법
다양성: 액세스-제어-요청-헤더

이것은 Spring doc과 많은 예시에서 빠졌지만 답은 매우 쉬웠습니다.방금 CorsRegistry에서 allowCredentials() 메서드를 보고 레지스트리 메서드 체인에 .allowCredentials(true)를 추가하고 Access-Control-AllowCredentials 헤더를 다시 추가했습니다.

또한 더 이상 사용되지 않는 WebMvcConfigurerAdapter를 사용하지 않고 이제 WebMvcConfigurer를 구현하고 addCorsMappings() 메서드를 재정의합니다.

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("/**")
                .allowedOrigins(
                        "http://localhost:3000",..)
                .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                .allowCredentials(true)
        ;
    }
    
}

Spring Boot 2.0.x를 사용하는 경우

CORS 지원은 기본적으로 비활성화되며 management.endpoints가 설치된 후에만 활성화됩니다.web.message.allowed-message 속성이 설정되었습니다.다음 구성은 example.com 도메인에서 GET 및 POST 호출을 허용합니다.

경영진, 경영진web.message.allowed-messages=http://example.com management.message.message.web.message.allowed-message=GET, POST

자세한 내용은 다음을 참조하십시오.

스프링 부트 2.0.2를 사용하고 있습니다.저도 같은 문제가 있지만, 다음 코드를 사용하여 수정합니다.누가 가장 좋은 방법을 가지고 있습니까?

//    Miss `Access-Control-Allow-Origin` header in response using this bean. 
//    @Bean
//    CorsConfigurationSource corsConfigurationSource() {
//        CorsConfiguration configuration = new CorsConfiguration();
//        configuration.setAllowCredentials(true);
//        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
//        configuration.addAllowedMethod("*");
//        configuration.setAllowedOrigins(this.getAllowedOrigins());
//        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//        source.registerCorsConfiguration("/**", configuration);
//        return source;
//    }

    @Bean
    public FilterRegistrationBean<CorsFilter> initCorsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
        config.addAllowedMethod("*");
        config.setAllowedOrigins(this.getAllowedOrigins());
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }

1단계: Spring에는 이미 CorsFilter가 있습니다. 사용자 자신의 CorsFilter를 콩으로 등록하여 사용자 자신의 구성을 제공할 수도 있습니다.

@Bean
public CorsFilter corsFilter() {
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    final CorsConfiguration config = new CorsConfiguration();
    config.setAllowedOrigins(Collections.singletonList("http://localhost:3000")); // Provide list of origins if you want multiple origins
    config.setAllowedHeaders(Arrays.asList("Origin", "Content-Type", "Accept"));
    config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "OPTIONS", "DELETE", "PATCH"));
    config.setAllowCredentials(true);
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

2단계: 컨트롤러에 주석 달기@CrossOrigin주석

이것은 나에게 효과가 있습니다(Kotlin):

@Configuration
class CorsConfig : WebMvcConfigurer {
    override fun addCorsMappings(registry: CorsRegistry) {
        registry.addMapping("/**")
    }
}

언급URL : https://stackoverflow.com/questions/50184663/global-cors-configuration-breaks-when-migrating-to-spring-boot-2-0-x

반응형