Search code examples
javapostokhttphttp-authentication

okhttp post request with authentication


I am using the okhttp (4.4.0) java library to send a post request to a webservice i created. Additionally that webservice requires basic authentication and does only accept post-requests. The webservice is behind a proxy that simply forwards https requests to http requests on port 8080. My code looks like this:

    ...
    RequestBody formBody = new FormBody.Builder()
                        .add("foo", this.foo)
                        .add("bar", this.bar)
                        .build();

    Request request = new Request.Builder()
                        .url("https://localhost/myWebApp")
                        .addHeader("User-Agent", "OkHttp Bot")
                        .addHeader("Authorization", Credentials.basic("myUser", "myPwd"))
                        .post(formBody)
                        .build();
    try (Response response = client.newCall(request).execute()) {
      if (!response.isSuccessful()) {
        throw new IOException("Unexpected code " + response);
      }
      return response.body().bytes();
    } catch (IOException e) {
      e.printStackTrace();
    }
    ...

The request fails with the following error:

Unexpected code Response{protocol=http/1.1, code=501, message=Not Implemented, url=https://localhost/myWebApp/}

The webservice's 'myWebApp' doGet method is configured to send a 501 Not implemented status message. But as I do a post-request the doGet method should not get called.

By taking a look in the access log of my webserver I found the following:

    127.0.0.1 - - [30/Mar/2020:09:05:24 +0200] "POST /myWebApp HTTP/1.1" 302 -
    127.0.0.1 - myUser [30/Mar/2020:09:05:25 +0200] "GET /myWebApp/ HTTP/1.1" 501 1029

So there is both a post request and a get request. It looks like there is at first a try to send the post body (without authentication?) and then a get request with authentication which is denied by my webservice.

Is there a way to make this work for me? Am I missing something? Please help!


Solution

  • So it seems I solved my own problem. Thanks @Yuri for pointing me there. I just added a "/" at the end of the url in my code and it worked like a charm.

    ...
     Request request = new Request.Builder()
                            .url("https://localhost/myWebApp/")
                            .addHeader("User-Agent", "OkHttp Bot")
                            .addHeader("Authorization", Credentials.basic("myUser", "myPwd"))
                            .post(formBody)
                            .build();
    ...
    

    For some reason (I don't know yet but maybe someone else can enlighten me) any given url without a trailing slash is redirected to the same url with a trailing slash. Standard browsers can deal with this circumstance, the okhttp client seems to struggle there.