当前位置: 首页 > 知识库问答 >
问题:

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

段干高歌
2023-03-14

我使用带有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
0

带有以下浏览器通知:

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

XMLHttpRequest无法加载http://localhost:5000。请求的资源上没有“access-control-allow-origin”标头。因此,不允许访问源“http://localhost:3000”。响应的HTTP状态代码为401。

@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支持,但是我尝试用选项请求模拟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.3Spring引导。博文写道:

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

@Configuration
public class MyConfiguration {

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

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

编辑:

我找到了一个变通办法,那似乎很难看。我已经开始了一个针对spring boot的github问题,在这里我描述了解决方法:https://github.com/spring-projects/spring-boot/issues/5834

共有1个答案

皇甫俊雅
2023-03-14

Spring Security现在可以利用Spring MVC CORS支持了,我在这篇博客文章中介绍了这一点。

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

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

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()...
    }
}
@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;
    }
}

这种方法取代了以前推荐的基于筛选器的方法。

您可以在Spring Security文档的专用CORS部分中找到更多详细信息。

 类似资料:
  • 我有Kafka Streams java应用程序启动并运行。我试图使用KSQL创建简单的查询,并使用Kafka流来实现复杂的解决方案。我希望将KSQL和Kafka流作为Java应用程序运行。 我打算通过https://github.com/confluentinc/ksql/blob/master/ksqldb-examples/src/main/java/io/confluent/ksql/em

  • 要获取请求URL,可以在堆栈溢出中找到以下方法。 第一种方法: 第二种方法: 第三种方法: 我不知道在spring boot应用程序中使用哪一个来获取请求URL。 如果我使用第三种方法,那么我是否需要在配置类中创建RequestContextListener的bean,如下所示?

  • 我在学习Spring Boot时遇到了一些编码问题;我想添加一个像Spring3.x那样的CharacterEncodingFilter。就像这样:

  • 问题内容: 我将Spring Boot与Spring Security和Cors支持一起使用。 如果我执行以下代码 结果我得到了 如果我使用错误的凭证进行测试,例如 我得到的不是401(这是Spring安全中错误身份验证的标准代码) 带有以下浏览器通知: 获取http:// localhost:5000 / api / token XMLHttpRequest无法加载http:// localho

  • 问题内容: 我希望我的React.js应用程序中的类可以从-files中导出,就像从CSS模块中导出时一样,但是我找不到任何现成的解决方案来解决这个问题。 我找到了在使用Create React App创建的应用程序中设置CSS模块的指南。 我了解您需要运行并以某种方式重写配置文件, 但是如何-我不明白。 问题答案: 您需要在项目中安装下一个npm-packages: 手写笔 测针器 CSS加载器