authenticationheadervalue - java restful basic authentication example
Http Basic Authentication en Java utilizando HttpClient? (9)
Estoy tratando de imitar la funcionalidad de este comando Curl en Java:
curl --basic --user username:password -d "" http://ipaddress/test/login
Escribí lo siguiente usando Commons HttpClient 3.0 pero de alguna manera terminé obteniendo un 500 Internal Server Error
del 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 luego probé un 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();
}
}
Aquí hay algunos puntos:
Podría considerar actualizar a HttpClient 4 (en términos generales, si puede, no creo que la versión 3 todavía sea compatible).
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 predeterminado (no estoy seguro). Lo que podría ser útil para probar es que la autenticación preventiva funciona mejor:client.getParams().setAuthenticationPreemptive(true);
De lo contrario, la principal diferencia entre curl -d ""
y lo que estás haciendo en Java es que, además de Content-Length: 0
, curl 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
todos modos.
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();
}
}
}
Gracias por todas las respuestas anteriores, pero para mí, no puedo encontrar la clase de Base64Encoder, así que me las arreglo a mi manera.
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 devuelve una cadena casi igual con
DatatypeConverter.printBase64Binary()
pero termine con "/ r / n", el servidor devolverá "solicitud incorrecta".
También funciona el código siguiente, 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 servicio chino 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();
}
}
Has probado esto (usando la versión 4 de HttpClient)
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();
HttpBasicAuth funciona para mí con pequeños cambios
Yo uso la dependencia maven
<dependency> <groupId>net.iharder</groupId> <artifactId>base64</artifactId> <version>2.3.8</version> </dependency>
Cambio más pequeño
String encoding = Base64.encodeBytes ((user + ":" + passwd).getBytes());
Ok, 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();
}
}
}
Una pequeña actualización - con suerte útil para alguien - me funciona en mi proyecto:
Uso la buena clase de dominio público Base64.java de Robert Harder (Gracias Robert - Código disponible aquí: Base64 - descarga y ponlo en tu paquete).
y realice una descarga de un archivo (imagen, documento, etc.) con autenticación y escriba 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();
}
}
}
mientras usa la matriz de encabezado
String auth = Base64.getEncoder().encodeToString(("test1:test1").getBytes());
Header[] headers = {
new BasicHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()),
new BasicHeader("Authorization", "Basic " +auth)
};
para HttpClient siempre use 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);