【问题标题】:How to configure CORS in a Spring Boot + Spring Security application?如何在 Spring Boot + Spring Security 应用程序中配置 CORS?
【发布时间】:2016-08-26 10:08:39
【问题描述】:

我使用带有 Spring Security 和 Cors 支持的 Spring Boot。

如果我执行以下代码

url = 'http://localhost:5000/api/token'
xmlhttp = new XMLHttpRequest
xmlhttp.onreadystatechange = ->
    if xmlhttp.readyState is 4
        console.log xmlhttp.status
xmlhttp.open "GET", url, true
# xmlhttp.setRequestHeader "X-Requested-With", "XMLHttpRequest"
xmlhttp.setRequestHeader 'Authorization', 'Basic ' + btoa 'a:a'
do xmlhttp.send

我得到了结果

200

如果我使用错误的凭据进行测试,例如

url = 'http://localhost:5000/api/token'
xmlhttp = new XMLHttpRequest
xmlhttp.onreadystatechange = ->
    if xmlhttp.readyState is 4
        console.log xmlhttp.status
xmlhttp.open "GET", url, true
# xmlhttp.setRequestHeader "X-Requested-With", "XMLHttpRequest"
xmlhttp.setRequestHeader 'Authorization', 'Basic ' + btoa 'a:aa'
do xmlhttp.send

我得到的不是 401(这是 Spring Security 中错误身份验证的标准代码)

0

带有以下浏览器通知:

获取http://localhost:5000/api/token

XMLHttpRequest 无法加载 http://localhost:5000。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'http://localhost:3000' 不允许访问。响应的 HTTP 状态代码为 401。

我正在开发前端代码,需要来自服务器响应的有用 http 状态代码来处理这种情况。我需要比 0 更有用的东西。响应正文也是空的。我不知道我的配置是错误的,还是软件错误,我也不知道是铬(使用arch linux)还是弹簧安全。

我的 Spring 配置是:

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

@RestController
@RequestMapping("api")
public class Controller {
    @RequestMapping("token")
    @CrossOrigin
    Map<String, String> token(HttpSession session) {
        return Collections.singletonMap("token", session.getId());
    }
}

@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("a").password("a").roles("USER");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
                .anyRequest().authenticated()
                .and().httpBasic();
    }
}

如果我用 curl 测试一切正常,我认为因为不需要 CORS 支持,但我尝试使用 OPTION 请求模拟 CORS,结果也可以。

$ curl -v localhost:5000/api/token -H "Authorization: Basic YTpha"
*   Trying ::1...
* Connected to localhost (::1) port 5000 (#0)
> GET /api/token HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.48.0
> Accept: */*
> Authorization: Basic YTpha
> 
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< Access-Control-Allow-Origin: http://localhost:3000
< Access-Control-Allow-Methods: POST,GET,OPTIONS,DELETE
< Access-Control-Max-Age: 3600
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: Origin,Accept,X-Requested-    With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization
< x-auth-token: 58e4cca9-7719-46c8-9180-2fc16aec8dff
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 01 May 2016 16:15:44 GMT
< 
* Connection #0 to host localhost left intact
{"token":"58e4cca9-7719-46c8-9180-2fc16aec8dff"}

并且凭据错误:

$ curl -v localhost:5000/api/token -H "Authorization: Basic YTp"
*   Trying ::1...
* Connected to localhost (::1) port 5000 (#0)
> GET /api/token HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.48.0
> Accept: */*
> Authorization: Basic YTp
> 
< HTTP/1.1 401 Unauthorized
< Server: Apache-Coyote/1.1
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< Pragma: no-cache
< Expires: 0
< X-Frame-Options: DENY
< WWW-Authenticate: Basic realm="Realm"
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 01 May 2016 16:16:15 GMT
< 
* Connection #0 to host localhost left intact
{"timestamp":1462119375041,"status":401,"error":"Unauthorized","message":"Failed to decode basic authentication token","path":"/api/token"}

编辑: 以免产生误会。我使用 1.3.3 Spring Boot。 博客文章写道:

CORS 支持将在即将发布的 Spring Boot 1.3 版本中提供,并且已经在 1.3.0.BUILD-SNAPSHOT 版本中提供。

在 Spring Boot 应用程序中使用带有 @CrossOrigin 注解的控制器方法 CORS 配置不需要任何特定配置。

可以通过使用自定义的 addCorsMappings(CorsRegistry) 方法注册 WebMvcConfigurer bean 来定义全局 CORS 配置:

我添加了以下代码以启用全局 cors 支持。实际上我以前试过这个,但结果是一样的。我最近又试了一次,结果还是一样。

@Configuration
public class MyConfiguration {

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

虽然问题来自授权过程之间的重定向,但这个想法很有趣。如何更改重定向到任何资源以避免这种冲突?

编辑:

我想我离解决方案更近了。我已经使用支持 cors 的 nodejs 服务器进行了测试,通过添加 访问控制允许来源:* 对所有请求。

就像 Stefan Isele 已经提到的,似乎 spring 安全重定向或不添加 CORS 标头,所以这就是请求似乎被破坏的原因。因此,当 Spring Security 检查身份验证时,它必须添加正确的标头。

有人知道怎么做吗?

编辑:

我找到了一种解决方法,这似乎很难看。我已经为 Spring Boot 启动了一个 github 问题,我在其中描述了解决方法:https://github.com/spring-projects/spring-boot/issues/5834

【问题讨论】:

  • 它是否也适用于 PUT 请求,或者我们必须单独定义它。默认情况下,所有来源和 GET、HEAD 和 POST 方法都是允许的。来自 Spring 文档 ^^

标签: javascript spring spring-security spring-boot cors


【解决方案1】:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:3000")
                .allowCredentials(true);
    }
}

截至 2021 年,这可能是最简单的解决方案,只需要创建一个单独的类。

就是这样。

【讨论】:

    【解决方案2】:

    如何在 Spring Boot 2.3+ 上解决 CORS

    总结

    如果您遇到此 CORS 问题,请不要担心。这是每个后端开发人员首次尝试与前端微服务集成时的常见问题。这是浏览器为了用户安全而严格应用的某种安全策略,这就是为什么当您通过 Postman/Swagger 或 cURL 尝试您的 API 时不会面对它的原因。

    解决方案

    • 客户端绕过(仅限开发人员)

    以下解决方案仅用于开发目的,您绝对需要为您的生产环境永久解决此 CORS 问题。您可以使用以下浏览器扩展来绕过浏览器策略以解决 CORS 错误,但如果它们不能正常工作,请不要感到惊讶。

    1. CORS 解锁 Firefox - Chrome
    2. CORS 无处不在Firefox
    • 生产解决方案

    有多种方法可以在应用程序上配置 CORS 策略,并且完全基于您的部署架构。例如,如果您的应用程序将通过反向代理(如 Nginx)、API 网关 (Kong)、Service Mesh Sidecar 代理(即 Envoy)、Kubernetes NGINX Ingress 等公开,最佳实践是处理边缘层上的 CORS 配置,因为有时他们不会考虑较低层的标头,并且会覆盖它们,您仍然会从浏览器收到 CORS 错误。 我在下面列出了用于配置边缘层的有用链接

    但是,如果您要通过 SprintBoot 的内置 Web 服务器部署和公开您的 API,您可以使用接下来的说明。

    全局启用 CORS 的说明 - Spring Boot 应用程序

    如果您没有任何 WebSecurityConfig 实现,只需轻松执行以下步骤:

    1. 添加以下依赖项 [spring-boot-starter-security] 到你的 pom.xml
    <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    1. 在您的配置包中创建一个新类,该类扩展 WebSecurityConfig(即“SecurityConfig”)
    2. 将以下代码放入创建的文件中:
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.web.cors.CorsConfiguration;
    
    import java.util.List;
    
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter
    {
    
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
            corsConfiguration.setAllowedOrigins(List.of("*"));
            corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PUT","OPTIONS","PATCH", "DELETE"));
            corsConfiguration.setAllowCredentials(true);
            corsConfiguration.setExposedHeaders(List.of("Authorization"));
            
            // You can customize the following part based on your project, it's only a sample
            http.authorizeRequests().antMatchers("/**").permitAll().anyRequest()
                    .authenticated().and().csrf().disable().cors().configurationSource(request -> corsConfiguration);
    
        }
    }
    
    1. 现在您需要根据需要自定义 CORS 配置:

      • setAllowedHeaders-> 您必须指定允许通过前端应用程序将哪些参数发送到后端服务,例如,如果您使用 Bearer/Basic Token Authorization 方法,您需要通过“授权”标头传递您的 JWT-Token。因此,您需要确保 backed 会相应地接受此数据,为此,您必须将“授权”放在 Allowed-Headers 列表中。

      • setAllowedMethods-> 不要忘记将“OPTIONS”方法放在飞行前过程的列表中。别担心,read more here!

      • setAllowCredentials-> 如果您使用的是 Authorization 标头,请将其设置为 True。

      • setExposedHeaders-> 如果是通过 Response Headers 返回数据,则需要在此处指定。例如,某些 API 旨在通过响应标头在成功/身份验证后返回授权令牌。因此,需要相应地暴露相关的标头。

      • setAllowedOrigins-> 您必须指定有资格向后端应用程序发送请求的域。例如,如果您的应用程序托管在 https://penguin.com 上并且您的 API 在 https://api.penguin.com 上,您需要允许“https://penguing.com”向您的后端发送请求。此外,您可以传递通配符 (*) 以允许任何域向您的后端发送请求。但建议不要使用“any”,除非您提供公共 API 或部署在非生产环境中。

      对于那些可能认为 CORS 可以避免 API 被其他平台/在其他平台上滥用(即网络钓鱼目的)的人来说,存在一个重要的误解。 不是这样,CORS 策略是基于浏览器的策略,可以通过代理轻松绕过,因此只会使滥用过程更加困难,但不会产生免疫。

    2. 构建/运行您的应用程序,测试您的 API,然后休息(每个人都知道 CORS 令人头疼)

    替代解决方案

    您可以使用以下链接:

    Spring.io | Enabling Cross-Origin Requests for a RESTful Web Service

    Bealdung | CORS with Spring

    【讨论】:

    • 只有 14 个谢谢。我认为原因是因为谷歌没有显示在第一个。这个答案是我找到的最好的,非常感谢。
    • 这为我节省了几个小时,谢谢!一个对我完全有用的小改动,将这一行 corsConfiguration.setAllowedOrigins 更改为 corsConfiguration.setAllowedOriginPatterns
    • @Soroosh Khodami 在同一个域上是否有严格的方法,但对于端口,例如:www.corscheck.com:8081 www.corscheck.com:8056 端口可能会改变,但域将保持不变同样,我怎么能限制只检查域(域事先不知道,它们可能会根据客户而改变)
    • @Shamitha Silva 我认为 HTTP 请求标头中没有源端口的迹象。所以应该在防火墙中管理。
    【解决方案3】:
    // https://docs.spring.io/spring-boot/docs/2.4.2/reference/htmlsingle/#boot-features-cors
    @Configuration
    public class MyConfiguration {
    
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurer() {
                @Override
                public void addCorsMappings(final CorsRegistry registry) {
                    registry.addMapping("/**").allowedMethods("*").allowedHeaders("*");
                }
            };
        }
    }
    

    如果使用 Spring Security,设置附加:

    // https://docs.spring.io/spring-security/site/docs/5.4.2/reference/html5/#cors
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(final HttpSecurity http) throws Exception {
            // ...
    
            // if Spring MVC is on classpath and no CorsConfigurationSource is provided,
            // Spring Security will use CORS configuration provided to Spring MVC
            http.cors(Customizer.withDefaults());
        }
    }
    

    【讨论】:

      【解决方案4】:
      @Bean
          public WebMvcConfigurer corsConfigurer() {
              return new WebMvcConfigurer() {
                  @Override
                  public void addCorsMappings(CorsRegistry registry) {
                      registry.addMapping("/**").allowedOrigins("*").allowedMethods("*");
                  }
              };
          }
      

      【讨论】:

      • 不要只是添加答案,试着解释你的答案。
      • WebMvsConfigure 是一个 bean 创建的。 addMapping("") 表示任何端点,addOrigins("") 表示任何主体都可以访问,allowedMathods("*") 可以提供任何类型的请求
      • 感谢您的解释;)谢谢,这就是我想要的。
      【解决方案5】:

      你可以只用一个单个类来完成这个,只需将它添加到你的类路径中。

      对于Spring BootSpring Security,这个一个就足够了,仅此而已。 :

              @Component
              @Order(Ordered.HIGHEST_PRECEDENCE)
              public class MyCorsFilterConfig implements Filter {
      
                  @Override
                  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
                      final HttpServletResponse response = (HttpServletResponse) res;
                      response.setHeader("Access-Control-Allow-Origin", "*");
                      response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
                      response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, enctype");
                      response.setHeader("Access-Control-Max-Age", "3600");
                      if (HttpMethod.OPTIONS.name().equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
                          response.setStatus(HttpServletResponse.SC_OK);
                      } else {
                          chain.doFilter(req, res);
                      }
                  }
      
                  @Override
                  public void destroy() {
                  }
      
                  @Override
                  public void init(FilterConfig config) throws ServletException {
                  }
      
      
              }
      

      【讨论】:

        【解决方案6】:

        Webflux (Reactive) Spring Boot 的解决方案,因为在使用“Reactive”搜索同一问题时,Google 将其显示为最佳结果之一。使用 Spring Boot 2.2.2 版

        @Bean
        public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
          return http.cors().and().build();
        }
        
        @Bean
        public CorsWebFilter corsFilter() {
          CorsConfiguration config = new CorsConfiguration();
        
          config.applyPermitDefaultValues();
        
          config.addAllowedHeader("Authorization");
        
          UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
          source.registerCorsConfiguration("/**", config);
        
          return new CorsWebFilter(source);
        }
        

        举个完整的例子,使用自定义身份验证管理器的设置(在我的例子中是 JWT 身份验证)。看这里https://gist.github.com/FiredLight/d973968cbd837048987ab2385ba6b38f

        【讨论】:

          【解决方案7】:

          我通过以下方式解决了这个问题:

          import javax.servlet.FilterChain;
          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          
          import org.springframework.context.annotation.Configuration;
          import org.springframework.web.cors.CorsConfigurationSource;
          import org.springframework.web.filter.CorsFilter;
          
              @Configuration
              public class CORSFilter extends CorsFilter {
          
                  public CORSFilter(CorsConfigurationSource source) {
                      super((CorsConfigurationSource) source);
                  }
          
                  @Override
                  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                          throws ServletException, IOException {
          
                      response.addHeader("Access-Control-Allow-Headers",
                              "Access-Control-Allow-Origin, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
                      if (response.getHeader("Access-Control-Allow-Origin") == null)
                          response.addHeader("Access-Control-Allow-Origin", "*");
                      filterChain.doFilter(request, response);
                  }
          
              }
          

          和:

          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Configuration;
          import org.springframework.http.HttpMethod;
          import org.springframework.web.cors.CorsConfiguration;
          import org.springframework.web.cors.CorsConfigurationSource;
          import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
          
              @Configuration
              public class RestConfig {
          
                  @Bean
                  public CORSFilter corsFilter() {
                      CorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                      CorsConfiguration config = new CorsConfiguration();
                      config.addAllowedOrigin("http://localhost:4200");
                      config.addAllowedMethod(HttpMethod.DELETE);
                      config.addAllowedMethod(HttpMethod.GET);
                      config.addAllowedMethod(HttpMethod.OPTIONS);
                      config.addAllowedMethod(HttpMethod.PUT);
                      config.addAllowedMethod(HttpMethod.POST);
                      ((UrlBasedCorsConfigurationSource) source).registerCorsConfiguration("/**", config);
                      return new CORSFilter(source);
                  }
              }
          

          【讨论】:

            【解决方案8】:

            如果您使用的是 Spring Security,您可以执行以下操作以确保首先处理 CORS 请求:

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

            更多信息请参见Spring 4.2.x CORS

            如果没有 Spring Security,这将起作用:

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

            【讨论】:

            • 我在我的 MainApplicationFile 中复制了名为“Without Spring Security”的代码解决方案,但它不起作用:(
            • 这些都不适合我。我不断收到带有选项请求的 401。
            • 完美运行!重要的是要记住(如您所说)如果您使用的是 Spring Security,您应该使用第一个代码 sn-p 以确保首先处理 CORS 请求......这就是我的案例的关键。非常感谢!
            【解决方案9】:

            在大量搜索来自 javascript CORS 的错误之后,我为这种情况找到的唯一优雅的解决方案是配置 Spring 自己的类 org.springframework.web.cors.CorsConfiguration.CorsConfiguration() 的 cors

            @Configuration
            @EnableWebSecurity
            public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
            
                @Override
                protected void configure(HttpSecurity http) throws Exception {
                    http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());
                }
            

            【讨论】:

              【解决方案10】:

              Kotlin 解决方案

              ...
              http.cors().configurationSource {
                CorsConfiguration().applyPermitDefaultValues()
              }
              ...
              

              【讨论】:

                【解决方案11】:

                我在 Axios、Spring Boot 和 Spring Security 的身份验证方面遇到了重大问题。

                请注意您使用的 Spring Boot 版本和 Spring Security。

                春季启动:1.5.10 春天:4.3.14 Spring Security 4.2.4

                为了使用基于注释的 Java 配置解决此问题,我创建了以下类:

                @Configuration
                @EnableWebSecurity
                public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                
                    @Autowired
                    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
                
                        auth.inMemoryAuthentication()
                                .withUser("youruser").password("yourpassword")
                                .authorities("ROLE_USER");
                    }
                
                    @Override
                    protected void configure(HttpSecurity http) throws Exception {
                
                        http.cors().and().
                                authorizeRequests()
                                .requestMatchers(CorsUtils:: isPreFlightRequest).permitAll()
                                .anyRequest()
                                .authenticated()
                                .and()
                                .httpBasic()
                                .realmName("Biometrix");
                
                        http.csrf().disable();
                
                    }
                
                    @Bean
                    CorsConfigurationSource corsConfigurationSource() {
                        CorsConfiguration configuration = new CorsConfiguration();
                        configuration.setAllowCredentials(true);
                        configuration.setAllowedHeaders(Arrays.asList("Authorization"));
                        configuration.setAllowedOrigins(Arrays.asList("*"));
                        configuration.setAllowedMethods(Arrays.asList("*"));
                        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                        source.registerCorsConfiguration("/**", configuration);
                        return source;
                    }
                }
                

                Axios 的主要问题之一是,当您的 API 需要身份验证时,它会发送带有 OPTIONS 请求的 Authorization 标头。如果你没有在允许的 headers 配置设置中包含 Authorization,我们的 OPTIONS 请求(又名 PreFlight 请求)将会失败并且 Axios 会报错。

                您可以通过几个简单且正确放置的设置看到,使用 SpringBoot 配置 CORS 非常简单。

                【讨论】:

                • 我一直在寻找这个解决方案。这个对我有用,谢谢。
                【解决方案12】:

                Spring Security 现在可以利用我写的 this blog post 中描述的 Spring MVC CORS 支持。

                要使其工作,您需要在 Spring Security 级别显式启用 CORS 支持,如下所示,否则启用 CORS 的请求可能会在到达 Spring MVC 之前被 Spring Security 阻止。

                如果您使用控制器级别的@CrossOrigin 注释,您只需启用 Spring Security CORS 支持,它将利用 Spring MVC 配置:

                @EnableWebSecurity
                public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                
                    @Override
                    protected void configure(HttpSecurity http) throws Exception {
                        http.cors().and()...
                    }
                }
                

                如果您更喜欢使用 CORS 全局配置,您可以声明一个 CorsConfigurationSource bean,如下所示:

                @EnableWebSecurity
                public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                
                    @Override
                    protected void configure(HttpSecurity http) throws Exception {
                        http.cors().and()...
                    }
                
                    @Bean
                    CorsConfigurationSource corsConfigurationSource() {
                        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                        source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
                        return source;
                    }
                }
                

                这种方法取代了之前推荐的filter-based approach

                您可以在 Spring Security 文档的dedicated CORS section 中找到更多详细信息。

                【讨论】:

                • 我使用 CorsFilter bean 使 CORS+Spring Security 工作。由于某种原因,FilterRegistrationBean 没有被拾取。
                • 嗨,我有这个: 在我的 dispatcher-servlet 中。这: 在我的 security.xml 中。但是当我打开身份验证时它不起作用。没有日志记录。有什么线索吗?
                • 补充一点,如果你使用@RepositoryRestResource,你必须专门启用它,另一种方式:stackoverflow.com/questions/31724994/…
                • 嗨,我正在尝试第二种方式,但是 Springs 将每个 JWT 令牌解码为“anonymousUser”。
                【解决方案13】:

                Cors 可能会让人头疼,但有了这个简单的代码,你只是 Cors !!!到指定的方法

                @CrossOrigin(origins="*")// in this line add your url and thats is all for spring boot side
                    @GetMapping("/some")
                    public String index() {
                        return "pawned cors!!!!";
                    }
                

                就像 spring boot 2.0.2 中的魅力

                【讨论】:

                  【解决方案14】:

                  我通过以下方式解决了这个问题: `

                  @Bean
                  CorsConfigurationSource corsConfigurationSource() {
                      CorsConfiguration configuration = new CorsConfiguration();
                      configuration.setAllowedOrigins(Arrays.asList("*"));
                      configuration.setAllowCredentials(true);
                      configuration.setAllowedHeaders(Arrays.asList("Access-Control-Allow-Headers","Access-Control-Allow-Origin","Access-Control-Request-Method", "Access-Control-Request-Headers","Origin","Cache-Control", "Content-Type", "Authorization"));
                      configuration.setAllowedMethods(Arrays.asList("DELETE", "GET", "POST", "PATCH", "PUT"));
                      UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                      source.registerCorsConfiguration("/**", configuration);
                      return source;
                  }
                  

                  `

                  【讨论】:

                    【解决方案15】:

                    我在返回服务器状态的方法上遇到了同样的问题。 该应用程序部署在多台服务器上。所以我发现最简单的就是添加

                    @CrossOrigin(origins = "*")
                    @RequestMapping(value="/schedulerActive")
                    public String isSchedulerActive(){
                      //code goes here
                    }
                    

                    此方法不安全,但您可以为此添加allowCredentials

                    【讨论】:

                      【解决方案16】:

                      如果你使用 JDK 8+,有一个单行 lambda 解决方案:

                      @EnableWebSecurity
                      public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                      
                      @Override
                      protected void configure(HttpSecurity http) throws Exception {
                          http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());
                      }
                      

                      【讨论】:

                      • 它到底是做什么的? javascript 客户端请求将不再抱怨“被 CORS 策略阻止”?
                      • 解决了我在使用 Axios 进行 POST 请求时遇到相同 CORS 异常的问题。
                      【解决方案17】:

                      为 Spring-Boot、Spring-Security 和基于 Java 的配置找到了一个简单的解决方案:

                      @Configuration
                      @EnableWebSecurity
                      @EnableGlobalMethodSecurity(prePostEnabled = true)
                      public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                      
                          @Override
                          protected void configure(HttpSecurity httpSecurity) throws Exception {
                              httpSecurity.cors().configurationSource(new CorsConfigurationSource() {
                                  @Override
                                  public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
                                      return new CorsConfiguration().applyPermitDefaultValues();
                                  }
                              });
                          }
                      }
                      

                      【讨论】:

                      • 你不需要@Configuration,如果你使用@EnableWebSecurity
                      • 这适用于我的情况
                      【解决方案18】:

                      用于属性配置

                      # ENDPOINTS CORS CONFIGURATION (EndpointCorsProperties)
                      endpoints.cors.allow-credentials= # Set whether credentials are supported. When not set, credentials are not supported.
                      endpoints.cors.allowed-headers= # Comma-separated list of headers to allow in a request. '*' allows all headers.
                      endpoints.cors.allowed-methods=GET # Comma-separated list of methods to allow. '*' allows all methods.
                      endpoints.cors.allowed-origins= # Comma-separated list of origins to allow. '*' allows all origins. When not set, CORS support is disabled.
                      endpoints.cors.exposed-headers= # Comma-separated list of headers to include in a response.
                      endpoints.cors.max-age=1800 # How long, in seconds, the response from a pre-flight request can be cached by clients.
                      

                      【讨论】:

                      • 这些属性仅适用于 Spring Actuator,并不适用于所有端点。
                      【解决方案19】:

                      跨源保护是浏览器的一项功能。正如您所假设的,Curl 不关心 CORS。 这就解释了为什么您的 curl 成功,而浏览器请求却没有。

                      如果您使用错误的凭据发送浏览器请求,spring 将尝试将客户端转发到登录页面。 此响应(在登录页面外)不包含标题“Access-Control-Allow-Origin”,浏览器会按照您的描述做出反应。

                      您必须使 spring 包含此登录响应的 haeder,并且可能用于其他响应,例如错误页面等。

                      这可以这样完成:

                          @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-support-in-spring-framework复制的

                      我将首先为所有资源添加 cors 映射:

                      registry.addMapping("/**")
                      

                      并且还允许所有方法标头.. 一旦它起作用,您可能会开始再次将其减少到所需的最低限度。

                      请注意,CORS 配置随版本 4.2 发生变化。

                      如果这不能解决您的问题,请发布您从失败的 ajax 请求中获得的响应。

                      【讨论】:

                        猜你喜欢
                        • 2021-11-06
                        • 2018-06-21
                        • 1970-01-01
                        • 2020-05-29
                        • 2017-03-06
                        • 2019-05-08
                        相关资源
                        最近更新 更多