Question

I am writing a Java lib and need to perform a request to a URL - currently using async-http-client from ning - and fetch its content. So I have a get method that returns a String of the content of the fetched document. However, to be able to get it, I must perform a HTTP basic authentication and I'm not succeeding at this in my Java code:

public String get(String token) throws IOException {
    String fetchURL = "https://www.eventick.com.br/api/v1/events/492";

    try {
        String encoded = URLEncoder.encode(token + ":", "UTF-8");
        return this.asyncClient.prepareGet(fetchURL)
        .addHeader("Authorization", "Basic " + encoded).execute().get().getResponseBody();
    }
}

The code returns no error, it just doesn't fetch the URL because the authentication header is not being properly set, somehow.

With curl -u option I can easily get what I want:

curl https://www.eventick.com.br/api/v1/events/492 -u 'xxxxxxxxxxxxxxx:'

Returns:

{"events":[{"id":492,"title":"Festa da Bagaceira","venue":"Mangueirão de Paulista",
"slug":"bagaceira-fest", "start_at":"2012-07-29T16:00:00-03:00",
"links":{"tickets":[{"id":738,"name":"Normal"}]}}]}

How can this be done in Java? With the async-http-client lib? Or if you know how to do it using another way..

Any help is welcome!

Was it helpful?

Solution

You're close. You need to base 64 encode rather than URL encode. That is, you need

String encoded = Base64.getEncoder().encodeToString((user + ':' + password).getBytes(StandardCharsets.UTF_8));

rather than

String encoded = URLEncoder.encode(token + ":", "UTF-8");

(Note that for the benefit of others, since I'm answering 2 years later, in my answer I'm using the more standard "user:password" whereas your question has "token:". If "token:" is what you needed, then stick with that. But maybe that was part of the problem, too?)

Here is a short, self-contained, correct example

package so17380731;

import com.ning.http.client.AsyncHttpClient;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.ws.rs.core.HttpHeaders;

public class BasicAuth {

    public static void main(String... args) throws Exception {
        try(AsyncHttpClient asyncClient = new AsyncHttpClient()) {
            final String user = "StackOverflow";
            final String password = "17380731";
            final String fetchURL = "https://www.eventick.com.br/api/v1/events/492";
            final String encoded = Base64.getEncoder().encodeToString((user + ':' + password).getBytes(StandardCharsets.UTF_8));
            final String body = asyncClient
                .prepareGet(fetchURL)
                .addHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoded)
                .execute()
                .get()
                .getResponseBody(StandardCharsets.UTF_8.name());
            System.out.println(body);
        }
    }
}

OTHER TIPS

The documentation is very sketchy, but I think that you need to use a RequestBuilder following the pattern shown in the Request javadoc:

Request r = new RequestBuilder().setUrl("url")
    .setRealm((new Realm.RealmBuilder()).setPrincipal(user)
    .setPassword(admin)
    .setRealmName("MyRealm")
    .setScheme(Realm.AuthScheme.DIGEST).build());
r.execute();

(Obviously, this example is not Basic Auth, but there are clues as to how you would do it.)


FWIW, one problem with your current code is that a Basic Auth header uses base64 encoding not URL encoding; see the RFC2617 for details.

basically, do it like this: BoundRequestBuilder request = asyncHttpClient .preparePost(getUrl()) .setHeader("Accept", "application/json") .setHeader("Content-Type", "application/json") .setRealm(org.asynchttpclient.Dsl.basicAuthRealm(getUser(), getPassword())) // ^^^^^^^^^^^-- this is the important part .setBody(json);

Test can be found here: https://github.com/AsyncHttpClient/async-http-client/blob/master/client/src/test/java/org/asynchttpclient/BasicAuthTest.java

This is also another way of adding Basic Authorization, you can use any of two the classes for your use AsyncHttpClient,HttpClient,in this case i will use AsyncHttpClient

AsyncHttpClient client=new AsyncHttpClient();           
        Request request = client.prepareGet("https://www.eventick.com.br/api/v1/events/492").
            setHeader("Content-Type","application/json")
            .setHeader("Authorization","Basic b2pAbml1LXR2LmNvbTpnMGFRNzVDUnhzQ0ZleFQ=")
            .setBody(jsonObjectRepresentation.toString()).build();

after adding header part

            ListenableFuture<Response> r = null;
            //ListenableFuture<Integer> f= null;
            try{
            r = client.executeRequest(request);
            System.out.println(r.get().getResponseBody());
            }catch(IOException e){

            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            client.close();

it may be useful for you

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top