Domanda

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!

È stato utile?

Soluzione

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

Altri suggerimenti

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top