2010-07-19 21 views
101

estoy tratando de imitar la funcionalidad de este comando curl en Java:Http Basic Authentication in Java using HttpClient?

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

escribí lo siguiente utilizando los Comunes HttpClient 3.0 pero de alguna manera terminó encima de conseguir un 500 Internal Server Error desde el servidor. ¿Puede alguien decirme si estoy haciendo algo mal?

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

Y más tarde probé una Commons HttpClient 4.0.1 pero sigue siendo el mismo error:

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(); 
     } 
} 
+0

um, cuál es el error a aparecer en los registros del servidor? – hvgotcodes

+0

Ah ... No tengo acceso a los registros del servidor :( – Legend

+0

La mayoría de las veces la clave de autorización que estamos utilizando podría estar equivocada. Compruebe http://dev.tapjoy.com/faq/how-to- find-sender-id-and-api-key-for-gcm/para ver si está usando la clave correcta o no. También me confundí al seleccionar la clave API para firebase Tenemos que usar SENDER ID - API KEY pair en Cloud ficha Mensaje de configuración bajo firebase es decir Ir a base de fuego App -.> Ir a la configuración de aplicación -.> mensajería en la nube allí se puede encontrar ID del remitente <==> API clave y esta clave de API se puede utilizar para enviar FCM – Rahul

Respuesta

74

Ok por lo que este funciona. Por si alguien lo quiere, aquí está la versión que funciona para mí :)

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

    } 

} 
+17

donde puede Encuentro Base64Encoder? –

+2

@Muhannad en Apache commons códec –

+4

No se puede encontrar 'Base64Encoder'. Jonas puede alegar se da el frasco completo? Además, ¿cuál es el nombre de clase completo de 'Base64Encoder'? – Jus12

7

Éstos son algunos puntos:

  • Se podría considerar la actualización a HttpClient 4 (hablando en términos generales, si es posible , No creo que la versión 3 todavía sea apoyada activamente).

  • Un código de estado 500 es un error del servidor, por lo que podría ser útil ver lo que dice el servidor (¿hay alguna pista en el cuerpo de respuesta que está imprimiendo?). Aunque podría ser causado por su cliente, el servidor no debería fallar de esta manera (un código de error 4xx sería más apropiado si la solicitud es incorrecta).

  • Creo que setDoAuthentication(true) es el valor predeterminado (no estoy seguro). Lo que podría ser útil para tratar la autenticación funciona es preventivo mejor:

    client.getParams().setAuthenticationPreemptive(true); 
    

De lo contrario, la principal diferencia entre curl -d "" y lo que está haciendo en Java es que, además de Content-Length: 0, rizo también envía Content-Type: application/x-www-form-urlencoded. Tenga en cuenta que, en términos de diseño, probablemente deba enviar una entidad con su solicitud POST de todos modos.

125

Has probado esto (usando HttpClient versión 4)

String encoding = Base64Encoder.encode ("test1:test1"); 
HttpPost httppost = new HttpPost("http://host:post/test/login"); 
httppost.setHeader("Authorization", "Basic " + encoding); 

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

¿En qué biblioteca está disponible Base64Encoder? –

+1

'sun.misc.Base64Encoder'. –

+20

Es mejor usar 'java.util.Base64' a partir de Java 8:' Base64.getEncoder(). EncodeToString (("test1: test1"). GetBytes()); ' – berry120

13

Una pequeña actualización - espero sea de utilidad para alguien - que funciona para mí en mi proyecto:

  • uso el buen Pública Clase de dominio Base64.java de Robert Harder (Gracias Robert - Código disponible aquí: Base64 - descárguelo y póngalo en su paquete).

  • y realice una descarga de un archivo (imagen, documento, etc.) Con autenticación y escribir en el disco local

Ejemplo:

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(); 
    } 
} 
} 
+2

Me sale 'El método encodeBytes (byte []) no está definido para el tipo Base64' –

+0

La clase Base64 personalizada se puede reemplazar por' import org.apache.commons.codec.binary.Base64; 'como [detallado en esta respuesta en esta página] (http://stackoverflow.com/a/24618341/26510) –

+2

En java 8, puede usar: import java.util.Base64; –

2

HttpBasicAuth funciona para mí con pequeños cambios

  1. utilizo la dependencia Maven

    <dependency> 
        <groupId>net.iharder</groupId> 
        <artifactId>base64</artifactId> 
        <version>2.3.8</version> 
    </dependency> 
    
  2. Smal ler cambiar

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

para HttpClient utilice siempre HttpRequestInterceptor por ejemplo

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

Gracias por todas las respuestas anteriores, pero para mí, no puedo encontrar la clase Base64Encoder, así que ordenar mi camino de todas formas.

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

} 

Una cosa más, también probé

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

NO funciona debido a que devuelva una cadena casi lo mismo con

DatatypeConverter.printBase64Binary() 

pero terminan con "\ r \ n" , el servidor devolverá "solicitud incorrecta".

También funciona el siguiente código, de hecho lo soluciono primero, pero por alguna razón, NO funciona en algún entorno de nube (sae.sina.com.cn si quieres saber, es un chino servicio de almacenamiento en la nube). entonces debe usar el encabezado http en lugar de las credenciales de HttpClient.

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(); 
    } 
} 
+0

Base64.encodeBase64String ("usuario: passwd" .getBytes()); trabajó para mi. DatatypeConverter.printBase64Binary() también funcionó para mí. Podría ser que cometió un error en el cuerpo del mensaje en el caso anterior y que causó una mala solicitud. O tal vez depende del servidor. – rents

+0

¡Oh dios! gracias, también trabajando para mi caso:] – xxxvodnikxxx

12

Este es el código de la respuesta aceptada anteriormente, con algunos cambios realizados con respecto a la codificación Base64. El código a continuación compila.

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

durante el uso conjunto de cabecera

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