13

The following code doesn't authenticate the user (no authentication failure happens, but the call fails due to lack of permissions):

def remote = new HTTPBuilder("http://example.com")
remote.auth.basic('username', 'password')
remote.request(POST) { req ->
    uri.path = "/do-something"
    uri.query = ['with': "data"]

    response.success = { resp, json ->
        json ?: [:]
    }
}

But the following works fine:

def remote = new HTTPBuilder("http://example.com")
remote.request(POST) { req ->
    uri.path = "/do-something"
    uri.query = ['with': "data"]
    headers.'Authorization' = 
                "Basic ${"username:password".bytes.encodeBase64().toString()}"

    response.success = { resp, json ->
        json ?: [:]
    }
}

Why isn't the first one working?

dmahapatro
  • 49,365
  • 7
  • 88
  • 117
Noel Yap
  • 18,822
  • 21
  • 92
  • 144
  • 2
    How does it fail? The server should return an HTTP 401 status code to trigger the basic authentication. HttpBuilder will then send a second request with the Authorization header. – ataylor Oct 18 '13 at 20:27
  • It just doesn't work. The request itself returns with a message saying the user doesn't have permissions to perform the operation. I can change the username and password to something completely invalid and the same thing happens. – Noel Yap Oct 18 '13 at 20:42
  • 2
    This should potentially solve your problem http://stackoverflow.com/questions/6588256/using-groovy-http-builder-in-preemptive-mode – Sandeep Singhal Nov 17 '13 at 04:41

2 Answers2

1

Two things that I can think of off the top of my head.

The .setHeaders method requires a map. Have you tried
'Authorization' : "Basic ${"username:password".bytes.encodeBase64().toString()}" ?

If not, It's a bit more work and code, but you could user the URIBuilder as well. Generally I encapsulate to a different class

protected final runGetRequest(String endpointPassedIn, RESTClient Client){
      URIBuilder myEndpoint = new URIBuilder(new URI(Client.uri.toString() + endpointPassedIn))
      HttpResponseDecorator unprocessedResponse = Client.get(uri: myEndpoint) as HttpResponseDecorator
      def Response = unprocessedResponse.getData() as LazyMap
      return Response
}

Hope this helps

Lucas Crostarosa
  • 1,192
  • 6
  • 13
  • 26
0

Looks like your server isn't fully HTTPBuilder-compilant. It should return 401 code (which is standart behaviour for REST servers, but non-standart for others) for HTTPBuilder to catch this status and resend authentication request. Here is written about it.

asm0dey
  • 2,841
  • 2
  • 20
  • 33