2017-07-31 170 views
1

最近我已经为我的Springboot和Angualr2应用程序引入了JWT身份验证。 在那里,我试图在我的Angualr代码传递JWT如下令牌请求Springboot和Angular2的HTTP自定义授权标头

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; 
 

 
     } 
 
    }

但是在它返回的服务器端做一个POST请求状态代码401.问题出现在Springboot方面,它检查授权标题如下,它返回null

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

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

enter image description here

然后我继续读下去,发现这可能是与CORS配置的问题。因此,我修改了我的CORS配置过滤器,使其具有addExposedHeader,如下所示

@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); 
} 

服务器仍然抱怨找不到授权标头。我错过了这里的任何事情吗?感谢您的帮助

解决方案

阅读下面的sideshowbarker的评论之后,我能够理解这个问题背后的基本知识。 在我的项目中我有一个JWT令牌过滤器,它内部总是检查授权标头。然后,我有如下修改它,现在它按预期工作

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); 
    } 
} 

}

回答

3

您必须配置春季后端代码不要求授权OPTIONS请求。

有关的具体帮助,请参阅下面的答案:

在SCRE的Access-Control-Request-HeadersAccess-Control-Request-Method请求头问题中的表示表示浏览器正在执行CORS preflight OPTIONS request

而且在您的要求AuthorizationContent-Type: application/json请求头的存在是什么触发你的浏览器做CORS预检,试图通过在代码中POST请求之前发送OPTIONS请求春天服务器。而且因为OPTIONS预检失败,浏览器将停止在那里,从来没有尝试的POST

所以发生了什么事是:

  1. 你的代码的,告诉你的浏览器,它希望发送与Authorization头的请求。
  2. 您的浏览器说好的,请求Authorization标头要求我执行CORS预检OPTIONS以确保服务器允许使用Authorization标头的请求。
  3. 您的浏览器发送OPTIONS请求到服务器没有Authorization,因为OPTIONS检查的整个目的是看它是否确定,包括头。
  4. 你的服务器发现的OPTIONS请求,但不是应对它表示它允许请求Authorization头的方式,将其与401,因为它缺乏头拒绝。
  5. 您的浏览器预计为CORS预检一个200或204的响应,而是获取401响应。所以,你的浏览器停在那里,从来没有试图从你的代码POST请求。

所以,你必须弄清楚你目前的服务器端代码部分导致您的服务器需要授权OPTIONS请求,并且您需要更改,以便它,而不是响应OPTIONS请求与200或204成功响应,而不需要授权。

+0

我有一个JWT令牌滤波器和内它总是检查授权报头。我必须修改该逻辑来忽略用于令牌过滤的OPTION请求并设置状态200 – keth