CORS问题-所请求的资源上不存在"Access-Control-Allow-Origin"标头 [英] CORS issue - No 'Access-Control-Allow-Origin' header is present on the requested resource

查看:102
本文介绍了CORS问题-所请求的资源上不存在"Access-Control-Allow-Origin"标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了两个Web应用程序-客户端和服务应用程序.
当客户端和服务应用程序部署在相同的Tomcat实例中时,它们之间的交互就很好.
但是,当将应用程序部署到单独的Tomcat实例(不同的计算机)中时,在请求发送服务应用程序时出现以下错误.

I have created two web applications - client and service apps.
The interaction between client and service apps goes fine when they are deployed in same Tomcat instance.
But when the apps are deployed into seperate Tomcat instances (different machines), I get the below error when request to sent service app.

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 401

我的客户端应用程序使用JQuery,HTML5和Bootstrap.

My Client application uses JQuery, HTML5 and Bootstrap.

如下所示进行AJAX呼叫服务:

AJAX call is made to service as shown below:

var auth = "Basic " + btoa({usname} + ":" + {password});
var service_url = {serviceAppDomainName}/services;

if($("#registrationForm").valid()){
    var formData = JSON.stringify(getFormData(registrationForm));
    $.ajax({
        url: service_url+action,
        dataType: 'json',
        async: false,
        type: 'POST',
        headers:{
            "Authorization":auth
        },
        contentType: 'application/json',
        data: formData,
        success: function(data){
            //success code
        },
        error: function( jqXhr, textStatus, errorThrown ){
            alert( errorThrown );
        });
}

我的服务应用程序使用Spring MVC,Spring Data JPA和Spring Security.

My service application uses Spring MVC, Spring Data JPA and Spring Security.

我包括了CorsConfiguration类,如下所示:

I have included CorsConfiguration class as shown below:

CORSConfig.java:

@Configuration
@EnableWebMvc
public class CORSConfig extends WebMvcConfigurerAdapter  {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("*");
    }
}

SecurityConfig.java:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
@ComponentScan(basePackages = "com.services", scopedProxy = ScopedProxyMode.INTERFACES)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("authenticationService")
    private UserDetailsService userDetailsService;

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
        auth.authenticationProvider(authenticationProvider());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       http
                .authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().fullyAuthenticated();
        http.httpBasic();
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.csrf().disable();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        return authenticationProvider;
    }
}

Spring Security依赖项:

Spring Security dependencies:

 <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-config</artifactId>
            <version>3.2.3.RELEASE</version>
</dependency>
<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
            <version>3.2.3.RELEASE</version>
</dependency>

我正在使用 Apache Tomcat 服务器进行部署.

I am using Apache Tomcat server for deployment.

推荐答案

CORS的预检请求使用不带凭据的HTTP OPTIONS,请参见

CORS' preflight request uses HTTP OPTIONS without credentials, see Cross-Origin Resource Sharing:

否则,请发出预检请求.使用引荐来源作为覆盖引荐来源,并使用方法OPTIONS并设置以下附加约束,将引荐来源作为覆盖引荐来源,从来源来源开始获取请求URL:

Otherwise, make a preflight request. Fetch the request URL from origin source origin using referrer source as override referrer source with the manual redirect flag and the block cookies flag set, using the method OPTIONS, and with the following additional constraints:

  • 包括一个Access-Control-Request-Method标头,并将请求方法作为标头字段值(即使是简单方法也是如此).
  • 如果作者请求标头不为空,则包括一个Access-Control-Request-Headers标头,并以字母顺序按作者顺序将作者请求标头的标头字段名称列表以逗号分隔,作为标头字段值,每个都转换为ASCII小写字母(甚至如果一个或多个是一个简单的标头).
  • 排除作者请求标头.
  • 排除用户凭据.
  • 排除请求实体主体.
  • Include an Access-Control-Request-Method header with as header field value the request method (even when that is a simple method).
  • If author request headers is not empty include an Access-Control-Request-Headers header with as header field value a comma-separated list of the header field names from author request headers in lexicographical order, each converted to ASCII lowercase (even when one or more are a simple header).
  • Exclude the author request headers.
  • Exclude user credentials.
  • Exclude the request entity body.

您必须允许HTTP OPTIONS的匿名访问.

You have to allow anonymous access for HTTP OPTIONS.

您修改(简化)的代码:

Your modified (and simplified) code:

@Override
protected void configure(HttpSecurity http) throws Exception {
   http
       .authorizeRequests()
           .andMatchers(HttpMethod.OPTIONS, "/**").permitAll()
           .antMatchers("/login").permitAll()
           .anyRequest().fullyAuthenticated()
           .and()
       .httpBasic()
           .and()
       .sessionManagement()
           .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
           .and()
       .csrf().disable();
}

从Spring Security 4.2.0开始,您可以使用内置支持,请参见

Since Spring Security 4.2.0 you can use the built-in support, see Spring Security Reference:

19. CORS

Spring框架为CORS提供了一流的支持.必须在Spring Security之前处理CORS,因为飞行前请求将不包含任何cookie(即JSESSIONID).如果请求中不包含任何cookie,并且首先使用Spring Security,则该请求将确定用户未通过身份验证(因为请求中没有cookie),并拒绝该用户.

Spring Framework provides first class support for CORS. CORS must be processed before Spring Security because the pre-flight request will not contain any cookies (i.e. the JSESSIONID). If the request does not contain any cookies and Spring Security is first, the request will determine the user is not authenticated (since there are no cookies in the request) and reject it.

确保首先处理CORS的最简单方法是使用CorsFilter.用户可以使用以下内容提供CorsConfigurationSource来将CorsFilter与Spring Security集成:

The easiest way to ensure that CORS is handled first is to use the CorsFilter. Users can integrate the CorsFilter with Spring Security by providing a CorsConfigurationSource using the following:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http
          // by default uses a Bean by the name of corsConfigurationSource
          .cors().and()
          ...
  }

  @Bean
  CorsConfigurationSource corsConfigurationSource() {
      CorsConfiguration configuration = new CorsConfiguration();
      configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
      configuration.setAllowedMethods(Arrays.asList("GET","POST"));
      UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
      source.registerCorsConfiguration("/**", configuration);
      return source;
  }
}

这篇关于CORS问题-所请求的资源上不存在"Access-Control-Allow-Origin"标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆