2017-07-11 4 views
1

Ich habe einen Spring-Boot-REST-Service, der einige Methoden bietet. Sie sind geschützt durch CSRF und Benutzername/Passwort Basic Auth (https).Java Jersey POST Anfrage mit CSRF-Schutz

Aber wenn ich versuche, eine POST-Anfrage, es zu tun mit dem Statuscode 403 und die Nachricht fehlschlägt „Könnte die mitgelieferte CSRF-Token nicht überprüfen, weil die Sitzung nicht gefunden wurde“

Das ist mein Client-Code ist:

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

Die erste Anfrage endet mit Status 403 und der Meldung "Das angegebene CSRF-Token konnte nicht überprüft werden, weil Ihre Sitzung nicht gefunden wurde". Danach extrahiere ich das CSRF-Token erfolgreich aus dem Antwortheader. Aber die zweite Anfrage mit CSRF-Header schlägt mit dem gleichen Fehler fehl.

Tun Sie das gleiche in Postman funktioniert gut.

Irgendwelche Ideen wo ist mein Fehler und was mache ich falsch?

Antwort

0

Es ist wahrscheinlich ein Session-Cookie, den Sie auch zurücksenden müssen, wie JSESSIONID. Hol den Keks. Vom NewCookie Sie eine Cookie erstellen und sie auf die Anfrage

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

hinzufügen Wenn es nicht JSESSIONID ist, überprüfen Sie alle Cookies. Es könnte etwas anderes sein.

+0

Es gibt nur ein Cookie zurück, wenn Sie anrufen Karte cookies = response.getCookies(); Beim Postman sehe ich zwei Cookies: XSRF-TOKEN und JSESSIONID. Aber in meinem Java-Client bekomme ich nur XSRF-TOKEN –

+0

Hmm, das ist seltsam. Ich werde es etwas später testen. –

+0

Was genau sind die Schritte, die du im Postboten machst? –