programing

스프링 CORS 'Access-Control-Allow-Origin' 헤더가 없습니다.

lastmemo 2023. 3. 22. 20:39
반응형

스프링 CORS 'Access-Control-Allow-Origin' 헤더가 없습니다.

web.xml을 java config로 포팅한 후 다음과 같은 문제가 발생하였습니다.

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

몇 가지 스프링 레퍼런스를 바탕으로 다음과 같은 시도를 시도했습니다.

@Configuration
@ComponentScan(basePackageClasses = AppConfig.class, useDefaultFilters = false, includeFilters = {
        @Filter(org.springframework.stereotype.Controller.class) })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/*").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
                .allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
                        "Access-Control-Request-Headers")
                .exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
                .allowCredentials(true).maxAge(3600);
    }

}

선택한 값은 web.xml 필터에서 가져온 것입니다.

<filter>    
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
</init-param>
<init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
</init-param>
<init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
</init-param> </filter> <filter-mapping>

<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Spring java config 접근법이 web.xml 파일처럼 작동하지 않는 이유를 알고 계십니까?

registry.addMapping("/*")로로 합니다.registry.addMapping("/**")addCorsMappings★★★★★★ 。

이 Spring CORS 매뉴얼을 참조하십시오.

매뉴얼에서 -

애플리케이션 전체에서 CORS를 유효하게 하는 방법은 다음과 같습니다.

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

모든 속성을 쉽게 변경할 수 있으며 특정 경로 패턴에만 이 CORS 설정을 적용할 수 있습니다.

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
            .allowedOrigins("http://domain2.com")
            .allowedMethods("PUT", "DELETE")
            .allowedHeaders("header1", "header2", "header3")
            .exposedHeaders("header1", "header2")
            .allowCredentials(false).maxAge(3600);
    }
}

컨트롤러 방식 CORS 구성

@RestController
@RequestMapping("/account")
public class AccountController {
  @CrossOrigin
  @RequestMapping("/{id}")
  public Account retrieve(@PathVariable Long id) {
    // ...
  }
}

전체 컨트롤러에 대해 CORS를 활성화하려면:

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

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

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

컨트롤러 레벨과 메서드레벨의 양쪽의 CORS 설정도 사용할 수 있습니다.그 후 스프링은 양쪽 주석의 Atribut을 조합하여 Marge된 CORS 설정을 만듭니다.

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

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

    @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
    public void remove(@PathVariable Long id) {
        // ...
    }
}

유용한 팁 - 스프링 데이터 레스트를 사용하는 경우 다른 접근 방식이 필요합니다.

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

 @Override
 public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.getCorsRegistry().addMapping("/**")
            .allowedOrigins("http://localhost:9000");
  }
}

Omkar의 대답은 꽤 포괄적이다.

그러나 글로벌 구성 부분의 일부가 변경되었습니다.

스프링 부트 2.0.2에 따릅니다.RELEASE

버전 4.2에서 봄 MVC는 CORS를 지원합니다.Spring Boot 어플리케이션에서 컨트롤러 방식의 CORS 설정을 @CrossOrigin 주석과 함께 사용하는 경우 특별한 설정은 필요하지 않습니다.글로벌 CORS 설정은 커스터마이즈된 addCorsMappings(CorsRegistry) 메서드에 WebMvcConfigurer bean을 등록함으로써 정의할 수 있습니다(다음 예 참조).

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**");
            }
        };
    }
}

에서는 대부분의 이 ""를 사용하여 이루어집니다.WebMvcConfigurerAdapter, 단,

WebMvcConfigurerAdapter 유형은 사용되지 않습니다.

Spring 5부터는 WebMvcConfigurer 인터페이스만 구현하면 됩니다.

public class MvcConfig implements WebMvcConfigurer {

이는 Java 8이 WebMvcConfigurerAdapter 클래스의 기능을 포함하는 인터페이스에 기본 메서드를 도입했기 때문입니다.

같은 문제가 발생하여 다음과 같은 Spring의 XML 구성을 사용하여 해결했습니다.

컨텍스트 xml 파일에 추가

<mvc:cors>
    <mvc:mapping path="/**"
        allowed-origins="*"
        allowed-headers="Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Authorization, X-Requested-With, requestId, Correlation-Id"
        allowed-methods="GET, PUT, POST, DELETE"/>
</mvc:cors>

는 제 인 【REST API】【REST API】를 .WebConfig.java with with with with with with with 。

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**").allowedOrigins("*");
  }
} 

이것에 의해, 임의의 송신원이 API에 액세스 할 수 있게 되어, 스프링 프로젝트의 모든 컨트롤러에 적용됩니다.

Spring Security ver > = 4.2를 사용하는 경우 Apache의 지원 대신 Spring Security의 기본 지원을 사용할 수 있습니다.

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

위의 예는 컨트롤러에서의 CORS 설정 방법, 특정 컨트롤러 방식 등에 대한 정보도 얻을 수 있는 Spring 블로그 투고에서 복사한 것입니다.게다가 XML 의 설정 예와 스프링 부트 통합도 있습니다.

@Geofrey가 지적한 바와 같이 스프링 보안에서는 스프링 부트 보안 CORS와 같은 다른 접근법이 필요합니다.

퍼블릭 클래스 Tracking System Application {

    public static void main(String[] args) {
        SpringApplication.run(TrackingSystemApplication.class, args);
    }

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

}

모든 오리진(*)을 허용하려면 setAllowedOrigins 대신 setAllowedOriginPatterns를 사용합니다.

아래 링크를 클릭해 주세요.

https://github.com/spring-projects/spring-framework/issues/26111

어떤 이유로든 누군가가 여전히 CORS를 우회할 수 없는 경우, 어떤 브라우저가 당신의 요청에 접근하기를 원하는 헤더를 작성하십시오.

컨피규레이션파일 내에 이 콩을 추가합니다.

@Bean
public WebSecurityConfigurerAdapter webSecurity() {
    return new WebSecurityConfigurerAdapter() {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.headers().addHeaderWriter(
                    new StaticHeadersWriter("Access-Control-Allow-Origin", "*"));


        }
    };
}

이렇게 하면 모든 원본에서 교차 출처를 허용하고 있음을 브라우저에 알릴 수 있습니다.특정 경로로 제한하려면 "*"를 {'syslog://localhost:3000',""}(으)로 변경합니다.

이 동작에 대한 자세한 내용은http://https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example 를 참조해 주세요.

, 「 」라고 하는 .No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

cors를 올바르게 설정했지만 RouterFuncion의 webflux에서 누락된 것은 다음과 같은 accept 및 content type header APPLICATION_JSON이었습니다.

@Bean
RouterFunction<ServerResponse> routes() {
    return route(POST("/create")
                              .and(accept(APPLICATION_JSON))
                              .and(contentType(APPLICATION_JSON)), serverRequest -> create(serverRequest);
}

이렇게 해서 액세스 제어 허가 오리진이 존재하는 문제를 해결할 수 있습니다.

Spring 보안 추가 후 많은 개발자가 원산지 간 문제에 직면하게 됩니다.

  1. 사용자 정의 필터 클래스의 정의 추가

    public class CsrfTokenLogger implements Filter {
    
     private Logger logger =
          Logger.getLogger(CsrfTokenLogger.class.getName());
    
    @Override
    public void doFilter(
    ServletRequest request, 
    ServletResponse response, 
    FilterChain filterChain) 
      throws IOException, ServletException {
    
      Object o = request.getAttribute("_csrf");
      CsrfToken token = (CsrfToken) o;
    
     filterChain.doFilter(request, response);
      }
     }
    
  2. 구성 클래스에 사용자 정의 필터 추가

    @Configuration
    public class ProjectConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) 
    throws Exception {
    
    http.addFilterAfter(
            new CsrfTokenLogger(), CsrfFilter.class)
        .authorizeRequests()
            .antMatchers("/login*").permitAll()
            .anyRequest().authenticated();
     }
    }
    

나는 이 같은 문제를 이런 식으로 해결했다.으로는 이 입니다.@EnableWebSecurityprotected void configure(HttpSecurity http) throws Exception {}

여기서부터 변경:

@Configuration
public class WebConfig {

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedMethods("*");
        }
    };
}

}

여기에

@Configuration
@EnableWebSecurity
public class WebConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.antMatcher("/**").authorizeRequests().antMatchers("/**").permitAll().anyRequest().authenticated();
    http.cors().and().csrf().disable();
}

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedMethods("*");
        }
    }; 
  }
}

스프링 부트에서는 @CrossOrigin 주석을 사용하여 솔루션을 찾았습니다.

@Configuration
@CrossOrigin
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

Spring Data Rest가 실제로 다른 접근방식을 가지고 있다는 그의 답변은 리버스바인드가 옳았다.그러나 RepositoryRestConfigurerAdapter를 Import할 수 없어 그들이 제공한 코드샘플을 얻을 수 없었습니다.서류를 살펴본 후, 나는 대신 나에게 맞는 이 수업을 이용했다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;

@Configuration
class CustomRestMvcConfiguration {

    @Bean
    public RepositoryRestConfigurer repositoryRestConfigurer() {
        return new RepositoryRestConfigurer() {
            @Override
            public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
                cors.addMapping("/**")
                    .allowedOrigins("http://localhost:4200");
      }
    };
  }
}

Spring Security를 사용한Spring Boot 2.7.3에서도 같은 문제가 발생하였습니다.

이 Bean을 응용 프로그램에 추가하여 수정했습니다.이 경우 Security Config 클래스에 http.cors().and() 코드를 추가하지 않아도 동작합니다.

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**").allowedOrigins("*").allowedMethods("*");
            }
        };
    }

언급URL : https://stackoverflow.com/questions/35091524/spring-cors-no-access-control-allow-origin-header-is-present

반응형