cors issue-请求的资源上不存在“access control allow origin”头

jtw3ybtb  于 2021-07-12  发布在  Java
关注(0)|答案(7)|浏览(347)

我已经创建了两个web应用程序-客户端和服务应用程序。
当客户端和服务应用程序部署在同一个tomcat示例中时,它们之间的交互很好。
但是当应用程序被部署到不同的tomcat示例(不同的机器)中时,当请求发送服务应用程序时,我得到以下错误。

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。
ajax调用服务如下所示:

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 );
        });
}

我的服务应用程序使用springmvc、springdatajpa和springsecurity。
我已经包括了 CorsConfiguration 分类如下: 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安全依赖项:
disho6za

disho6za1#

cors的飞行前请求使用http OPTIONS 如果没有凭据,请参阅跨源资源共享:
否则,请发出飞行前请求。使用方法选项,使用referer source作为覆盖referer source,并设置手动重定向标志和block cookies标志,从源获取请求url,并具有以下附加约束:
包括一个访问控制请求方法头,头字段值为请求方法(即使这是一个简单的方法)。
如果author请求头不为空,则包括一个访问控制请求头,该头具有一个以逗号分隔的头字段名列表作为头字段值,这些头字段名按词典顺序来自author请求头,每个头字段名都转换为ascii小写(即使一个或多个头是简单头)。
排除作者请求头。
排除用户凭据。
排除请求实体主体。
您必须允许对http进行匿名访问 OPTIONS .
Spring 安全3
您的修改(和简化)代码:

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

您仍然需要cors配置(可能还有一些附加值):

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

Spring 安全4
由于SpringSecurity 4.2.0可以使用内置支持,请参阅SpringSecurity参考:
19cors公司
spring框架为cors提供了一流的支持。必须在 Spring 安检前处理COR,因为飞行前请求将不包含任何cookie(即 JSESSIONID ). 如果请求不包含任何cookies,并且spring security是第一个,那么请求将确定用户未通过身份验证(因为请求中没有cookies),并拒绝它。
确保首先处理cors的最简单方法是使用 CorsFilter . 用户可以集成 CorsFilter 通过提供 CorsConfigurationSource 使用以下方法:

@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;
  }
}
8zzbczxx

8zzbczxx2#

从SpringSecurity 4.1开始,这是使SpringSecurity支持cors的正确方法(SpringBoot 1.4/1.5中也需要):

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
    }
}

以及:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        http.csrf().disable();
        http.cors();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(ImmutableList.of("*"));
        configuration.setAllowedMethods(ImmutableList.of("HEAD",
                "GET", "POST", "PUT", "DELETE", "PATCH"));
        // setAllowCredentials(true) is important, otherwise:
        // The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
        configuration.setAllowCredentials(true);
        // setAllowedHeaders is important! Without it, OPTIONS preflight request
        // will fail with 403 Invalid CORS request
        configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

不要执行以下任何操作,这是解决问题的错误方法:
http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "/**").permitAll(); web.ignoring().antMatchers(HttpMethod.OPTIONS); 参考文献:http://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/cors.html

y3bcpkx1

y3bcpkx13#

在我的例子中,我启用了oauth安全性的资源服务器,而上面的任何解决方案都不起作用。经过一番调试和谷歌搜索后,我明白了原因。

@Bean
public FilterRegistrationBean corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");
    source.registerCorsConfiguration("/**", config);
    FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;
}

基本上在这个例子中 Ordered.HIGHEST_PRECEDENCE 这是关键!
https://github.com/spring-projects/spring-security-oauth/issues/938
不同的pom依赖项添加了不同类型的过滤器,因此我们可能会有基于顺序的问题。

wmtdaxz3

wmtdaxz34#

既然这些例子对我都没有帮助,我就凭自己的知识去做。通常最复杂的错误总是发生在我身上。我就是这样对付这个虫子的。
在这种方法中:

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration cors = new CorsConfiguration();
    cors.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "HEAD", "DELETE"));
    UrlBasedCorsConfigurationSource source = new
            UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
    return source;
}

corsconfiguration默认有允许的方法:post,head,get,so put,delete将不起作用!我所做的是创建corsconfiguration的新示例并设置允许的方法:

cors.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "HEAD", "DELETE"));

现在我的方法是:

@Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration cors = new CorsConfiguration();
        cors.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "HEAD", "DELETE"));
        UrlBasedCorsConfigurationSource source = new
                UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", cors.applyPermitDefaultValues());
        return source;
    }

就像魅力一样。我希望它能帮助别人。当然,所有其他配置都是由spring.io文档进行的

vcudknz3

vcudknz35#

试试这个:

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.Arrays;
import java.util.List;

@Component
public class CorsFilterConfig {

    public static final List<String> allowedOrigins = Arrays.asList("*");

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

fslejnso6#

这适用于:springbootstarter父版本2.2.6.release

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

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

在prod中将“*”更改为有意义的内容

xmjla07d

xmjla07d7#

在主应用程序中添加以下配置。我在springboot应用程序2.3.1中使用了它

package com.example.restservicecors;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@SpringBootApplication
public class RestServiceCorsApplication {

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

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

}

参考来源:https://spring.io/guides/gs/rest-service-cors/

相关问题