为什么Spring Security身份验证会导致CORS错误

时间:2019-01-30 23:17:32

标签: java spring spring-security cors

我有一个用Spring Boot,Security和Web用Java制造的后端服务器,以及一个用Angular制造的客户端。

目前,我正在尝试在localhost:8080/resource下进行一个简单的请求。

此地址的控制器显示如下:

@RestController
public class IndexController {
    @CrossOrigin
    @RequestMapping("/resource")
    public Map<String, Object> home() {
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("id", UUID.randomUUID().toString());
        model.put("content", "Hello World");

        return model;
    }
}

Angular客户端(执行请求的部分)是这样的:

import { Component } from "@angular/core";
import { HttpClient } from "@angular/common/http";

@Component({
    selector: "app-root",
    templateUrl: "./app.component.html",
    styleUrls: ["./app.component.css"]
})
export class AppComponent {
    public title = "Security Client";
    public greeting = {};

    constructor(private http: HttpClient) {
        http.get("http://localhost:8080/resource").subscribe(data => this.greeting = data);
    }
}

仅使用显示的问题就是我收到了CORS错误。

是从我的pom.xml中删除Spring Security还是添加此配置:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests().antMatchers("/resource").permitAll();
    }
}

解决问题。

我想知道的是为什么访问要求用户身份验证的地址时出现CORS错误而不是401 Unauthorized。

2 个答案:

答案 0 :(得分:1)

  

我想知道的是为什么我收到CORS错误而不是401   访问需要用户的地址时未经授权   身份验证。

出现此错误的原因是,在实际请求(POST,GET ...)之前,浏览器会执行飞行前请求( OPTIONS ),以验证实际上被叫服务器是否能够处理CORS请求。

在此请求期间,Access-Control-Request-MethodAccess-Control-Request-Header会得到验证,并将一些其他信息添加到标头中。

您收到CORS错误,是因为如果对OPTIONS请求的CORS验证失败,您甚至没有完成您的实际请求。

您可以查看CORS验证工作原理的流程图in here

有趣的一点是,当服务器无权回答OPTIONS请求时,在飞行前请求期间您只会获得HTTP错误状态,例如401。

答案 1 :(得分:0)

根据spring boot文档:

  

出于安全原因,浏览器禁止AJAX调用资源   在当前原点之外。例如,您可以拥有银行   一个标签页中的帐户,另一个标签页中的evil.com。来自evil.com的脚本   不能使用您的银行API向您的银行API发出AJAX请求   凭据-例如从您的帐户取钱!

     

跨源资源共享(CORS)是W3C规范   由大多数浏览器实施,可让您指定哪种类型的   授权跨域请求,而不是使用不太安全的请求   以及基于IFRAME或JSONP的功能不那么强大的解决方法。

您收到此错误,因为您需要在安全配置中添加过滤器。在您的配置中,添加:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.cors()
    .and()
    .authorizeRequests().antMatchers("/resource").permitAll();
}

在同一文件中,您应该添加:

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", 
    "DELETE", "OPTIONS"));
    configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", 
    "x-auth-token"));
    configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
    UrlBasedCorsConfigurationSource source = new 
    UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);

    return source;
}

这对我来说很好。