2017-07-31 145 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