如何在Spring Boot + Spring Security应用程序中配置CORS?

时间:2016-05-01 16:23:39

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

我使用Spring Boot和Spring Security以及Cors支持。

如果我执行以下代码

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安全性中错误身份验证的标准代码),我得到了

0

以下浏览器通知:

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

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

我正在开发需要服务器响应中有用的http状态代码来处理这种情况的前端代码。我需要比0更有用的东西。响应体也是空的。我不知道我的配置是否错误,或者它是一个软件错误,我也不知道它在哪里,如果它是铬(使用arch linux)还是Spring安全。

My Spring Config是:

@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配置:

我添加了以下代码以启用全球角色支持。实际上我之前尝试了这个,但结果是一样的。我最近再次尝试过,结果是一样的。

@Configuration
public class MyConfiguration {

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

这个想法,问题来自授权过程之间的重定向是一个有趣的。如何将重定向更改为任何资源以避免此冲突?

编辑:

我想我更接近解决方案。我已经测试了我的nodejs服务器,通过添加支持cors没有问题 Access-Control-Allow-Origin:* 对所有请求。

就像Stefan Isele已经提到的那样,Spring安全性似乎重定向或者没有添加CORS头,这就是为什么请求似乎被打破的原因。因此,虽然Spring安全性正在检查身份验证,但它必须添加正确的标头。

有谁知道怎么做?

编辑:

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

18 个答案:

答案 0 :(得分:33)

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

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

如果您正在使用控制器级别@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中找到更多详细信息。

答案 1 :(得分:17)

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

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());
}

答案 2 :(得分:14)

如果您使用的是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

答案 3 :(得分:8)

交叉源保护是浏览器的一项功能。正如你所假设的那样,Curl并不关心CORS。 这就解释了为什么你的卷发成功,而浏览器请求则没有。

如果您使用错误的凭据发送浏览器请求,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请求中获得的响应。

答案 4 :(得分:6)

Spring Boot 2.3+如何解决CORS问题

总结

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

解决方案

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

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

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

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

但是,如果您要通过 SprintBoot 的内置网络服务器部署和公开您的 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-> 如果您通过响应头返回数据,则需要在此处指定它们。例如,某些 API 旨在通过响应头在成功/身份验证后返回授权令牌。因此,需要相应地公开相关的标头。

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

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

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

替代解决方案

您可以使用以下链接:

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

Bealdung | CORS with Spring

答案 5 :(得分:4)

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

答案 6 :(得分:2)

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

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

}

和:

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

答案 7 :(得分:2)

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

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

`

答案 8 :(得分:2)

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!!!!";
    }

像春季靴子2.0.2中的魅力

答案 9 :(得分:2)

对于属性配置

# 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.

答案 10 :(得分:1)

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

public class Computer {

    //required parameters
    private String HDD;
    private String RAM;

    //optional parameters
    private boolean isGraphicsCardEnabled;
    private boolean isBluetoothEnabled;


    public String getHDD() {
        return HDD;
    }

    public String getRAM() {
        return RAM;
    }

    public boolean isGraphicsCardEnabled() {
        return isGraphicsCardEnabled;
    }

    public boolean isBluetoothEnabled() {
        return isBluetoothEnabled;
    }

    private Computer(ComputerBuilder builder) {
        this.HDD=builder.HDD;
        this.RAM=builder.RAM;
        this.isGraphicsCardEnabled=builder.isGraphicsCardEnabled;
        this.isBluetoothEnabled=builder.isBluetoothEnabled;
    }

    //Builder Class
    public static class ComputerBuilder{

        // required parameters
        private String HDD;
        private String RAM;

        // optional parameters
        private boolean isGraphicsCardEnabled;
        private boolean isBluetoothEnabled;

        public ComputerBuilder(String hdd, String ram){
            this.HDD=hdd;
            this.RAM=ram;
        }

        public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
            this.isGraphicsCardEnabled = isGraphicsCardEnabled;
            return this;
        }

        public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
            this.isBluetoothEnabled = isBluetoothEnabled;
            return this;
        }

        public Computer build(){
            return new Computer(this);
        }

    }

}

答案 11 :(得分:1)

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

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

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

答案 12 :(得分:1)

您只能使用单个课程完成此操作,只需将其添加到您的课程路径中即可。

对于 Spring Boot Spring 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 {
            }


        }

答案 13 :(得分:1)

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

答案 14 :(得分:0)

我在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标头。如果您未在允许的标头配置中包括“授权”,则我们的OPTIONS请求(也称为PreFlight请求)将失败,并且Axios将报告错误。

如您所见,通过几个简单且正确放置的设置,使用SpringBoot进行CORS配置非常简单。

答案 15 :(得分:0)

科特林溶液

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

答案 16 :(得分:0)

在大量搜索了来自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());
    }

答案 17 :(得分:0)

Webflux(反应式)Spring Boot解决方案,因为当使用“反应式”搜索相同问题时,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