Почему HTTPBuilder basic auth не работает?

Следующий код не аутентифицирует пользователя (при этом не происходит сбой аутентификации, но сбой вызова из-за отсутствия разрешений):

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 ?: [:]
    }
}

Но следующее прекрасно работает:

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 ?: [:]
    }
}

Почему не первый работает?

Ответ 1

Две вещи, которые я могу придумать с головы.

Для метода .setHeaders требуется карта. Пробовали ли вы 'Authorization' : "Basic ${"username:password".bytes.encodeBase64().toString()}"?

Если нет, это немного больше работы и кода, но вы также можете использовать URIBuilder. Обычно я инкапсулирую в другой класс

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
}

Надеюсь, что это поможет

Ответ 2

Похоже, ваш сервер не полностью компилируется HTTPBuilder. Он должен вернуть код 401 (что является стандартным поведением для серверов REST, но нестандартным для других) для HTTPBuilder, чтобы поймать этот статус и повторно отправить запрос на аутентификацию. Здесь написано об этом.