预检响应具有无效的 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