2017-07-31 12 views
1

最近、私はSpringbootとAngualr2ベースのアプリケーションに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; 
 

 
     } 
 
    }

しかし私Angualrコードでトークンとして以下のJWTを渡すことにより、POSTリクエストを実行しようとしましたステータスコード401です。問題はSpringboot側で以下のように承認ヘッダーをチェックし、nullを返します

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

次に、私はリクエストヘッダーを見て、以下のようにAccess-Control-Request-Headersの下に承認ヘッダーを持っています。しかし、それはサーバー側には見えません。

enter image description here

それから私は、さらに読み、これがCORS構成に問題がある可能性がありますことを見出しました。だから、私はまだサーバーがAuthorizationヘッダを見つけることができないと文句を言い

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

以下のようaddExposedHeaderを持っている私のCORS構成フィルタを変更しました。私はここで何かを逃したのですか?以下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リクエストヘッダの存在は、ブラウザがあなたのコードでPOST要求を試みる前に、春のサーバにOPTIONS要求を送信することにより、そのCORSのプリフライトを行うトリガするものです。そのOPTIONSプリフライトが失敗するため、ブラウザはすぐそこで停止し、POSTを試みることはありません。

だから何が起こっているかである:

  1. あなたのコードのは、それがAuthorizationヘッダーとリクエストを送信したいブラウザを伝えます。
  2. ブラウザでは、AuthorizationヘッダーのリクエストでCORSプリフライトOPTIONSを実行して、サーバーがAuthorizationヘッダーのリクエストを許可していることを確認する必要があります。
  3. OPTIONSチェックの全体の目的は、それがそのヘッダを含めてOKだかどうかを確認することですので、お使いのブラウザは、AuthorizationヘッダせずにサーバーOPTIONS要求を送信します。
  4. サーバーにはOPTIONSリクエストが表示されますが、要求にAuthorizationヘッダーを許可することを示す方法で応答するのではなく、ヘッダーがないため401で拒否します。
  5. ブラウザはCORSプリフライトの応答を200または204にする代わりに、その401応答を取得します。したがって、ブラウザはすぐに停止し、コードからPOSTリクエストを試みることはありません。

だから、あなたはあなたのサーバがOPTIONSリクエストの承認を必要とする原因となっている現在のサーバーサイドコードのどの部分を把握しなければならない、そしてそれは代わりに200または204とOPTIONS要求に応答するようにあなたがそれを変更する必要があります無許可での成功応答。

+0

私はJWTトークンフィルタを持っており、その内部には常に認証ヘッダーがチェックされています。私はそのロジックを変更してトークンフィルタリングのOPTION要求を無視し、ステータス200を設定しなければなりませんでした – keth

関連する問題