2017-07-11 15 views
1

私はいくつかの方法を提供するスプリングブートRESTサービスを持っています。それらはCSRFとユーザー名/パスワードBasic Auth(https)によって保護されています。CSRFプロテクションのJava Jersey POSTリクエスト

ApiMessage msg = new ApiMessage("Client1", "Key1", "Value1"); 

    // Set up Basic Authentication 
    HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder() 
      .nonPreemptive() 
      .credentials(ApiUser, ApiUserPassword) 
      .build(); 
    ClientConfig clientConfig = new ClientConfig(); 
    clientConfig.register(feature); 
    Client client = ClientBuilder.newClient(clientConfig); 

    // Set up client and target (ApiHost = URI for the request Ressource) 
    WebTarget target = client.target(ApiHost); 
    WebTarget checkTarget = target.path("check"); 
    Invocation.Builder invocationBuilder = checkTarget.request(MediaType.APPLICATION_JSON); 

    // Do a first request to get the CSRF Header 
    Response response = invocationBuilder.post(Entity.entity(msg, MediaType.APPLICATION_JSON)); 

    if (response.getStatus() == 200) { 

     System.out.println("Without CSRF - everything worked. "); 

    } else if (response.getStatus() == 403) { 

     System.out.println("CSRF Protection: " + response.getStatus() + response.readEntity(String.class)); 

     // Get CSRF Token out of the response 
     Map<String, NewCookie> cookies = response.getCookies(); 
     String csrf = cookies.get("XSRF-TOKEN").getValue(); 

     // Add the Token to the header and POST again 
     invocationBuilder.header("X-XSRF-TOKEN", csrf); 
     response = invocationBuilder.post(Entity.entity(msg, MediaType.APPLICATION_JSON)); 

     if (response.getStatus() != 200) { 
      System.out.println("Error: " + response.getStatus() + response.readEntity(String.class)); 
     } else { 
      System.out.println("With CSRF - everything worked. "); 
     } 
    } else { 
     System.out.println(response.getStatus() + " " + response.readEntity(String.class)); 
    } 
:私のクライアントコードです

しかし、私はPOSTを実行しようとするとき、それはステータスコード403とメッセージで失敗する要求は、「あなたのセッションが見つからなかったために提供CSRFトークンを確認できませんでした」

最初の要求はステータス403で終了し、「セッションが見つからなかったため、提供されたCSRFトークンを確認できませんでした」というメッセージが表示されます。 その後、レスポンスヘッダーからCSRFトークンが正常に抽出されます。 しかし、CSRFヘッダーを使用した2番目の要求は、同じエラーで失敗します。

郵便番号で同じことをすると正常に動作します。

私の間違いは何ですか、私は間違っていますか?

答えて

0

おそらくJSESSIONIDのように返信する必要のあるセッションクッキーがあります。そのクッキーを入手してください。 NewCookieからはCookieを作成し、それはJSESSIONIDない場合は、要求

NewCookie session = cookies.get("JSESSIONID"); 
Cookie cookie = session.toCookie(); 
invocationBuilder.cookie(cookie); 

に追加し、すべてのクッキーをご確認ください。それは別のものかもしれない。

+0

呼び出し時に1つのCookieバックしかありません。 Map cookies = response.getCookies(); 郵便配達員を見ると、XSRF-TOKENとJSESSIONIDという2つのCookieが表示されます。しかし、私のJavaクライアントでは、XSRF-TOKEN –

+0

しか得られません。それは奇妙です。私は少し後にそれをテストします。 –

+0

郵便配達員の手順は正確には何ですか? –

関連する問題