预检响应具有无效的 HTTP 状态代码 401 - Spring

Posted

技术标签:

【中文标题】预检响应具有无效的 HTTP 状态代码 401 - Spring【英文标题】:Response for preflight has invalid HTTP status code 401 - Spring 【发布时间】:2017-03-15 04:18:40 【问题描述】:

每个人。 我是 Angular 2 和 Spring Framework 的新手。 我正在尝试一个带有授权标头(基本身份验证)的简单获取请求。

我正在使用 Spring Boot (1.2.6.RELEASE),这也可能是相关的。 我的 CORS 配置如下所示。

@Component
public class SimpleCorsFilter implements Filter 

private final Logger log = LoggerFactory.getLogger(SimpleCorsFilter.class);

public SimpleCorsFilter() 
    log.info("SimpleCORSFilter init");


@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, authorization, x-auth-token");

    chain.doFilter(req, res);


@Override
public void init(FilterConfig filterConfig) 


@Override
public void destroy() 



这是从客户端看的样子

    this.headers.append('Authorization', 'Basic dXNlcjphZG1pbg==');
    return this.http
            .get(`http://localhost:8080/api/login?username=$username`, headers : this.headers )
            .map(response => response.json().data as any);

我不断得到:

XMLHttpRequest 无法加载 http://localhost:8080/api/login?username=user。预检响应 具有无效的 HTTP 状态代码 401

请帮忙,我不知道我错过了什么...... 我已经检查了很多帖子,但无法到达那里......

【问题讨论】:

HTTP 401 表示由于缺少授权而无法满足您的请求,请检查是否正常 能不能去掉response.setHeader("Access-Control-Allow-Credentials", "true");试试看? @TharsanSivakumar,有同样的想法,谢谢 相关:***.com/questions/30632200/… 【参考方案1】:

这可能会很晚,但这可以解决一些问题,经过长时间我找到了答案

public class SecurityConfig extends WebSecurityConfigurerAdapter

    @Override
    public void configure( WebSecurity web ) throws Exception
    
        web.ignoring().antMatchers( HttpMethod.OPTIONS, "/**" );
    

参考https://***.com/a/45830981/3724760

【讨论】:

这必须是最佳答案 - 经过数小时的 Spring 文档、github 和 SO 爬行后到达这里 我花了几个小时才终于找到了这个答案。【参考方案2】:

如果有人在使用 Spring Boot、Spring Security 和 angular 2/4 等客户端时遇到类似情况,我已经发布了调查结果 here。

对于那些正在寻找简短答案的人,您必须配置两件事:

    使用 Spring Boot,启用全局 CORS 的推荐方法是在 Spring MVC 中声明并结合细粒度 @CrossOrigin 配置为:

    @Configuration
    public class CorsConfig 
    
        @Bean
        public WebMvcConfigurer corsConfigurer() 
            return new WebMvcConfigurerAdapter() 
                @Override
                public void addCorsMappings(CorsRegistry registry) 
                    registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
                            .allowedHeaders("*");
                
            ;
        
    
    

    然后,在使用 Spring Security 时,您还必须在 Spring Security 级别启用 CORS,以允许它利用在 Spring MVC 级别定义的配置:

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

干杯!!!

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review @khelwood 更新了答案,但为什么要投反对票?这就像从封面判断一本书一样吗?如果我没有更新答案,我会很感激的。【参考方案3】:

http 方法为 OPTIONS 时避免过滤并设置状态 200

if("OPTIONS".equalsIgnoreCase(request.getMethod())) 
    response.setStatus(HttpServletResponse.SC_OK);
 else 
    chain.doFilter(req, res);

【讨论】:

感谢@Eswar,我不再收到错误消息了。但是,忽略 OPTIONS 请求是一个好的实现吗?我问是因为我真的不知道。 我们可以在没有过滤器的情况下验证请求标头并发送状态码。每当我们在标头中发送授权时,浏览器都会发出预检请求,因此我们只是在验证来源并抛出错误状态代码。忽略 OPTIONS 不会影响我们过滤的其他 http 方法,但我不确定它的实现是否良好。

以上是关于预检响应具有无效的 HTTP 状态代码 401 - Spring的主要内容,如果未能解决你的问题,请参考以下文章

预检响应具有无效的 HTTP 状态代码 401 - Spring

Angular 2 - 预检响应具有无效的 HTTP 状态代码 401

通过基本身份验证访问 REST 的 Angular2 抛出“预检响应具有无效的 HTTP 状态代码 401”

无法加载 http://localhost:9999/auth-service/oauth/token:预检响应具有无效的 HTTP 状态代码 401

Yii2 和 reactjs CORS 过滤器给出错误:预检响应具有无效的 HTTP 状态代码 401

预检响应具有无效的 HTTP 状态代码 404”