本文介绍了HTTP状态代码401,即使我在请求中发送凭据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我在基于Springboot和Angualr2的App中引入了JWT身份验证.在那里"中,我尝试通过在Angualr代码中传递以下JWT令牌来发出POST请求

Recently i have introduced JWT authentication to my Springboot and Angualr2 based App.In There i tried to do a POST request by passing the JWT token as below in my Angualr code

save(jobId: number, taskId: number, note: Note) {

   return this.http.post(environment.APIENDPOINT + '/jobs/' + jobId + '/tasks/' + taskId + '/notes', note, this.setHeaders()).map((response: Response) => response.json());

}
private setHeaders() {
        // create authorization header with jwt token
        let currentUser = JSON.parse(localStorage.getItem('currentUser'));
        console.log("Current token---"+ currentUser.token);
        if (currentUser && currentUser.token) {

  let headers = new Headers();
  headers.append('Content-Type', 'application/json');
  headers.append('authorization','Bearer '+ currentUser.token);

   let r = new RequestOptions({ headers: headers })
   return r;

        }
    }

但是,在服务器端,它返回状态代码401.问题出在Springboot端,它如下所示检查授权标头,并返回null

However in the server side it returns status code 401. The issue is in the Springboot side it checks the authorization header as below and it returns null

String authToken = request.getHeader("authorization ");

然后,我查看了请求标头,它在Access-Control-Request-Headers下具有授权标头,如下所示.但是它对服务器端不可见.

Then i had a look at the request header and it has the authorization header under Access-Control-Request-Headers as below. But it is not visible to the server side.

然后,我进一步阅读,发现这可能与CORS配置有关.所以我修改了我的CORS配置过滤器,使其具有如下的addExposedHeader

Then i read further and found that this could be an issue with CORS configuration. So i have modified my CORS configuration filter to have addExposedHeader as below

@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addExposedHeader("authorization");
    config.addAllowedMethod("OPTIONS");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("DELETE");

    //config.addExposedHeader("Content-Type");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}

服务器仍然抱怨找不到授权头.我在这里想念任何东西吗?感谢您的帮助

Still the server complains that it can not find the Authorization header. Did i miss any thing here? Appreciate your help

解决方案

阅读下面的sideshowbarker评论后,我能够理解问题的基本知识.在我的项目"中,我有一个JWT令牌过滤器,并且在其中始终检查Authorization标头.然后我如下修改了它,现在它可以按预期工作了

After reading the sideshowbarker's comment below, i was able to understand the basics behind the issue.In My Project I have a JWT token filter and inside that it always checks the Authorization header. Then i have modified it as below and now it works as expected

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
try {

    if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
        response.setStatus(HttpServletResponse.SC_OK);
    }else{
        String authToken = request.getHeader(this.tokenHeader);
        jWTTokenAuthenticationService.parseClaimsFromToken(authToken);
        --
    }
    chain.doFilter(request, response);
}Catch(AuthenticationException authEx){
    SecurityContextHolder.clearContext();
    if (entryPoint != null) {
        entryPoint.commence(request, response, authEx);
    }
}

}

推荐答案

您需要将服务器配置为不要求对OPTIONS请求进行授权(即,将请求发送到的服务器,而不是为您的服务器提供服务的服务器)前端代码).

You need to configure the server to not require authorization for OPTIONS requests (that is, the server the request is being sent to — not the one serving your frontend code).

那是因为发生了什么事

  1. 您的代码告诉您的浏览器它想要发送带有Authorization标头的请求.
  2. 您的浏览器说,好吧,带有Authorization头的请求要求我执行CORS预检OPTIONS,以确保服务器允许带有Authorization头的请求.
  3. 您的浏览器将OPTIONS请求发送到服务器而没有Authorization标头,因为OPTIONS检查的整个目的是查看是否可以包含该标头./li>
  4. 您的服务器看到了OPTIONS请求,但没有以表明它允许请求中使用Authorization标头的方式对其进行响应,而是由于缺少标头而以401拒绝了它.
  5. 您的浏览器期望CORS预检得到200或204的响应,但会得到401的响应.因此,您的浏览器会在那里停止,并且永远不会尝试通过您的代码发出POST请求.
  1. Your code’s telling your browser it wants to send a request with the Authorization header.
  2. Your browser says, OK, requests with the Authorization header require me to do a CORS preflight OPTIONS to make sure the server allows requests with the Authorization header.
  3. Your browser sends the OPTIONS request to the server without the Authorization header, because the whole purpose of the OPTIONS check is to see if it’s OK to include that header.
  4. Your server sees the OPTIONS request but instead of responding to it in a way that indicates it allows the Authorization header in requests, it rejects it with a 401 since it lacks the header.
  5. Your browser expects a 200 or 204 response for the CORS preflight but instead gets that 401 response. So your browser stops right there and never tries the POST request from your code.


更多详细信息:


Further details:

问题屏幕快照中的Access-Control-Request-HeadersAccess-Control-Request-Method请求标头表明浏览器正在执行 CORS飞行前选项请求.

The Access-Control-Request-Headers and Access-Control-Request-Method request headers in the screenshot in the question indicate the browser’s doing a CORS preflight OPTIONS request.

并且请求中出现AuthorizationContent-Type: application/json请求标头是触发浏览器执行CORS预检的原因-通过在尝试代码中的POST请求之前向服务器发送OPTIONS请求.而且由于OPTIONS预检失败,因此浏览器就在那里停止并且从不尝试POST.

And the presence of the Authorization and Content-Type: application/json request headers in your request are what trigger your browser do that CORS preflight — by sending an OPTIONS request to the server before trying the POST request in your code. And because that OPTIONS preflight fails, the browser stops right there and never attempts the POST.

因此,您必须确定请求发送到服务器上服务器中当前服务器端代码的哪一部分,以使其要求对OPTIONS请求进行授权,并对其进行更改,以使其对OPTIONS作出响应.无需授权即可获得200或204成功响应.

So you must figure out what part of the current server-side code on the server the request is being sent to causes it to require authorization for OPTIONS requests, and change that so it instead responds to OPTIONS with a 200 or 204 success response without authorization being required.

有关特别启用OPTIONS-启用Spring服务器的特定帮助,请参见以下答案:

For specific help on OPTIONS-enabling a Spring server in particular, see the following answers:

  • Disable Spring Security for OPTIONS Http Method
  • Spring CorsFilter does not seem to work still receiving a 401 on preflight requests
  • Response for preflight has invalid HTTP status code 401 - Spring
  • AngularJS & Spring Security with ROLE_ANONYMOUS still returns 401

这篇关于HTTP状态代码401,即使我在请求中发送凭据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 10:28