webentwicklung-frage-antwort-db.com.de

HTTP-Standardauthentifizierung in Java using HttpClient?

Ich versuche, die Funktionalität dieses Curl-Befehls in Java nachzuahmen:

curl --basic --user username:password -d "" http://ipaddress/test/login

Ich schrieb das folgende mit Commons HttpClient 3.0, bekam aber irgendwie ein 500 Internal Server Error vom Server. Kann mir jemand sagen, ob ich etwas falsch mache?

public class HttpBasicAuth {

    private static final String ENCODING = "UTF-8";

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {

            HttpClient client = new HttpClient();

            client.getState().setCredentials(
                    new AuthScope("ipaddress", 443, "realm"),
                    new UsernamePasswordCredentials("test1", "test1")
                    );

            PostMethod post = new PostMethod(
                    "http://address/test/login");

            post.setDoAuthentication( true );

            try {
                int status = client.executeMethod( post );
                System.out.println(status + "\n" + post.getResponseBodyAsString());
            } finally {
                // release any connection resources used by the method
                post.releaseConnection();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
   } 

Und ich habe später versucht, einen Commons HttpClient 4.0.1, aber immer noch den gleichen Fehler:

import Java.io.BufferedReader;
import Java.io.IOException;
import Java.io.InputStream;
import Java.io.InputStreamReader;

import org.Apache.http.HttpEntity;
import org.Apache.http.HttpResponse;
import org.Apache.http.auth.AuthScope;
import org.Apache.http.auth.UsernamePasswordCredentials;
import org.Apache.http.client.ClientProtocolException;
import org.Apache.http.client.methods.HttpPost;
import org.Apache.http.impl.client.DefaultHttpClient;


public class HttpBasicAuth {

    private static final String ENCODING = "UTF-8";

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        try {
            DefaultHttpClient httpclient = new DefaultHttpClient();

            httpclient.getCredentialsProvider().setCredentials(
                    new AuthScope(AuthScope.ANY_Host, AuthScope.ANY_PORT), 
                    new UsernamePasswordCredentials("test1", "test1"));

            HttpPost httppost = new HttpPost("http://Host:post/test/login");

            System.out.println("executing request " + httppost.getRequestLine());
            HttpResponse response;
            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();

            System.out.println("----------------------------------------");
            System.out.println(response.getStatusLine());
            if (entity != null) {
                System.out.println("Response content length: " + entity.getContentLength());
            }
            if (entity != null) {
                entity.consumeContent();
            }

            httpclient.getConnectionManager().shutdown();  
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}
140
Legend

Ok, das funktioniert also. Nur für den Fall, dass es jemand möchte, hier ist die Version, die für mich funktioniert :)

import Java.io.BufferedReader;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.net.HttpURLConnection;
import Java.net.URL;
import Java.util.Base64;


public class HttpBasicAuth {

    public static void main(String[] args) {

        try {
            URL url = new URL ("http://ip:port/login");
            String encoding = Base64.getEncoder().encodeToString(("test1:test1").getBytes(‌"UTF‌​-8"​));

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setRequestProperty  ("Authorization", "Basic " + encoding);
            InputStream content = (InputStream)connection.getInputStream();
            BufferedReader in   = 
                new BufferedReader (new InputStreamReader (content));
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch(Exception e) {
            e.printStackTrace();
        }

    }

}
104
Legend

Haben Sie dies versucht (mit HttpClient Version 4):

String encoding = Base64Encoder.encode(user + ":" + pwd);
HttpPost httpPost = new HttpPost("http://Host:post/test/login");
httpPost.setHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoding);

System.out.println("executing request " + httpPost.getRequestLine());
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
166
Buhake Sindi

Dies ist der Code aus der oben akzeptierten Antwort, wobei einige Änderungen in Bezug auf die Base64-Codierung vorgenommen wurden. Der folgende Code wird kompiliert.

import Java.io.BufferedReader;
import Java.io.InputStream;
import Java.io.InputStreamReader;
import Java.net.HttpURLConnection;
import Java.net.URL;

import org.Apache.commons.codec.binary.Base64;


public class HttpBasicAuth {

    public static void main(String[] args) {

        try {
            URL url = new URL ("http://ip:port/login");

            Base64 b = new Base64();
            String encoding = b.encodeAsString(new String("test1:test1").getBytes());

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setDoOutput(true);
            connection.setRequestProperty  ("Authorization", "Basic " + encoding);
            InputStream content = (InputStream)connection.getInputStream();
            BufferedReader in   = 
                new BufferedReader (new InputStreamReader (content));
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } 
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}
16
Mario

Ein kleines Update - hoffentlich nützlich für jemanden - es funktioniert für mich in meinem Projekt:

  • Ich benutze die Nice Public Domain Klasse Base64.Java von Robert Harder (Danke Robert - Code hier verfügbar: Base64 - downloade und packe ihn in dein Paket).

  • laden Sie eine Datei (Bild, Dokument usw.) mit Authentifizierung herunter und schreiben Sie sie auf die lokale Festplatte

Beispiel:

import Java.io.BufferedOutputStream;
import Java.io.File;
import Java.io.FileOutputStream;
import Java.io.InputStream;
import Java.io.OutputStream;
import Java.net.HttpURLConnection;
import Java.net.URL;

public class HttpBasicAuth {

public static void downloadFileWithAuth(String urlStr, String user, String pass, String outFilePath) {
    try {
        // URL url = new URL ("http://ip:port/download_url");
        URL url = new URL(urlStr);
        String authStr = user + ":" + pass;
        String authEncoded = Base64.encodeBytes(authStr.getBytes());

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setDoOutput(true);
        connection.setRequestProperty("Authorization", "Basic " + authEncoded);

        File file = new File(outFilePath);
        InputStream in = (InputStream) connection.getInputStream();
        OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
        for (int b; (b = in.read()) != -1;) {
            out.write(b);
        }
        out.close();
        in.close();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}
}
13

Hier sind ein paar Punkte:

  • Sie können ein Upgrade auf HttpClient 4 in Betracht ziehen (wenn Sie können, wird Version 3 meiner Meinung nach immer noch nicht aktiv unterstützt).

  • Ein 500-Statuscode ist ein Serverfehler. Daher kann es hilfreich sein, zu überprüfen, was der Server sagt (ein Hinweis auf den Antworttext, den Sie drucken?). Obwohl dies möglicherweise von Ihrem Client verursacht wird, sollte der Server nicht auf diese Weise ausfallen (ein 4xx-Fehlercode ist besser geeignet, wenn die Anforderung falsch ist).

  • Ich denke, setDoAuthentication(true) ist die Standardeinstellung (nicht sicher). Was nützlich sein könnte, um zu versuchen, ist, dass die präventive Authentifizierung besser funktioniert:

    client.getParams().setAuthenticationPreemptive(true);
    

Ansonsten ist der Hauptunterschied zwischen curl -d "" und was Sie in Java tun, ist, dass zusätzlich zu Content-Length: 0, curl sendet auch Content-Type: application/x-www-form-urlencoded. Beachten Sie, dass Sie in Bezug auf das Design wahrscheinlich trotzdem eine Entität mit Ihrer POST -Anforderung senden sollten.

7
Bruno

Danke für alle Antworten oben, aber für mich kann ich die Base64Encoder-Klasse nicht finden, also sortiere ich mich trotzdem aus.

public static void main(String[] args) {
    try {
        DefaultHttpClient Client = new DefaultHttpClient();

        HttpGet httpGet = new HttpGet("https://httpbin.org/basic-auth/user/passwd");
        String encoding = DatatypeConverter.printBase64Binary("user:passwd".getBytes("UTF-8"));
        httpGet.setHeader("Authorization", "Basic " + encoding);

        HttpResponse response = Client.execute(httpGet);

        System.out.println("response = " + response);

        BufferedReader breader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuilder responseString = new StringBuilder();
        String line = "";
        while ((line = breader.readLine()) != null) {
            responseString.append(line);
        }
        breader.close();
        String repsonseStr = responseString.toString();

        System.out.println("repsonseStr = " + repsonseStr);

    } catch (IOException e) {
        e.printStackTrace();
    }

}

Eine weitere Sache habe ich auch versucht

Base64.encodeBase64String("user:passwd".getBytes());

Es funktioniert NICHT, weil es eine Zeichenkette zurückgibt, die fast mit der gleichen Zeichenkette identisch ist

DatatypeConverter.printBase64Binary()

aber ende mit "\ r\n", dann gibt der Server "bad request" zurück.

Der folgende Code funktioniert auch, eigentlich sortiere ich ihn zuerst aus, aber aus irgendeinem Grund funktioniert er NICHT in einer Cloud-Umgebung (sae.sina.com.cn, wenn Sie wissen möchten, dass es sich um einen chinesischen Cloud-Dienst handelt). Müssen Sie also den http-Header anstelle von HttpClient-Anmeldeinformationen verwenden.

public static void main(String[] args) {
    try {
        DefaultHttpClient Client = new DefaultHttpClient();
        Client.getCredentialsProvider().setCredentials(
                AuthScope.ANY,
                new UsernamePasswordCredentials("user", "passwd")
        );

        HttpGet httpGet = new HttpGet("https://httpbin.org/basic-auth/user/passwd");
        HttpResponse response = Client.execute(httpGet);

        System.out.println("response = " + response);

        BufferedReader breader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuilder responseString = new StringBuilder();
        String line = "";
        while ((line = breader.readLine()) != null) {
            responseString.append(line);
        }
        breader.close();
        String responseStr = responseString.toString();
        System.out.println("responseStr = " + responseStr);

    } catch (IOException e) {
        e.printStackTrace();
    }
}
5
chenyi1976

HttpBasicAuth funktioniert bei mir mit kleineren Änderungen

  1. Ich benutze Maven-Abhängigkeit

    <dependency>
        <groupId>net.iharder</groupId>
        <artifactId>base64</artifactId>
        <version>2.3.8</version>
    </dependency>
    
  2. Kleinere Änderung

    String encoding = Base64.encodeBytes ((user + ":" + passwd).getBytes());
    
3
lynhnn

während der Verwendung von Header-Array

String auth = Base64.getEncoder().encodeToString(("test1:test1").getBytes());
Header[] headers = {
    new BasicHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()),
    new BasicHeader("Authorization", "Basic " +auth)
};
3
manoj

verwenden Sie für HttpClient beispielsweise immer HttpRequestInterceptor

httclient.addRequestInterceptor(new HttpRequestInterceptor() {
    public void process(HttpRequest arg0, HttpContext context) throws HttpException, IOException {
        AuthState state = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
        if (state.getAuthScheme() == null) {
            BasicScheme scheme = new BasicScheme();
            CredentialsProvider credentialsProvider = (CredentialsProvider) context.getAttribute(ClientContext.CREDS_PROVIDER);
            Credentials credentials = credentialsProvider.getCredentials(AuthScope.ANY);
            if (credentials == null) {
                System.out.println("Credential >>" + credentials);
                throw new HttpException();
            }
            state.setAuthScope(AuthScope.ANY);
            state.setAuthScheme(scheme);
            state.setCredentials(credentials);
        }
    }
}, 0);
3
EngrSofty

Eine einfache Möglichkeit, sich mit einem HTTP anzumelden POST ohne alle Base64-spezifischen Aufrufe ausführen ist die Verwendung des HTTPClient BasicCredentialsProvider

import Java.io.IOException;
import static Java.lang.System.out;
import org.Apache.http.HttpResponse;
import org.Apache.http.auth.AuthScope;
import org.Apache.http.auth.UsernamePasswordCredentials;
import org.Apache.http.client.CredentialsProvider;
import org.Apache.http.client.HttpClient;
import org.Apache.http.client.methods.HttpGet;
import org.Apache.http.client.methods.HttpPost;
import org.Apache.http.impl.client.BasicCredentialsProvider;
import org.Apache.http.impl.client.HttpClientBuilder;

//code
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(user, password);
provider.setCredentials(AuthScope.ANY, credentials);
HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();

HttpResponse response = client.execute(new HttpPost("http://address/test/login"));//Replace HttpPost with HttpGet if you need to perform a GET to login
int statusCode = response.getStatusLine().getStatusCode();
out.println("Response Code :"+ statusCode);
1
rjdkolb