2010-10-24 48 views
8

Estoy tratando de conectarme al Servidor Web Tomcat en mi máquina utilizando una autenticación resumida. Estoy usando el reino de la memoria de Tomcat. Aquí es cómo está configurado el servidor:Autenticación HTTP digest con HttpUrlConnection

1) En server.xml:

<Realm className="org.apache.catalina.realm.MemoryRealm" digest="MD5" /> 

2) En Tomcat-users.xml

<user username="testuser" password="81dc9bdb52d04dc20036dbd8313ed055" roles="test"/> 

3) En web.xml de mi web proyecto:

<auth-method>DIGEST</auth-method> 

como se puede ver que he especificado como un método de digestión "MD5" y he encryped la contraseña utilizando el digest.sh de Tom gato.

Aquí está mi código del lado del cliente:

private static void testGet() throws IOException { 

    // Create a URL 
    URL test = new URL("http://localhost:8080/TestWebProject/TestServlet"); 

    // Open a connection to the URL 
    HttpURLConnection conn = (HttpURLConnection) test.openConnection(); 

    MessageDigest md5 = null; 
    try { 
     md5 = MessageDigest.getInstance("MD5"); 
    } catch(NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 

    // Digest password using the MD5 algorithm 
    String password = "1234"; 
    md5.update(password.getBytes()); 
    String digestedPass = digest2HexString(md5.digest()); 

    // Set header "Authorization" 
    String credentials = "testuser:" + digestedPass; 
    conn.setRequestProperty("Authorization", "Digest " + credentials); 

    // Print status code and message 
    System.out.println("Test HTTP GET method:"); 
    System.out.println("Status code: " + conn.getResponseCode()); 
    System.out.println("Message: " + conn.getResponseMessage()); 
    System.out.println(); 

} 

private static String digest2HexString(byte[] digest) 
{ 
    String digestString=""; 
    int low, hi ; 

    for(int i=0; i < digest.length; i++) 
    { 
     low = (digest[i] & 0x0f) ; 
     hi = ((digest[i] & 0xf0)>>4) ; 
     digestString += Integer.toHexString(hi); 
     digestString += Integer.toHexString(low); 
    } 
    return digestString ; 
} 

Creo que mi código del lado del cliente es bueno y la configuración del servidor, también. Aunque el servidor me sigue enviando el código de estado 401 con el mensaje "No autorizado". Como no soy un desarrollador experimentado de Java, quiero preguntar si alguien tiene una idea o ve un error en mi implementación.

¡Gracias de antemano!

+0

En general, si la autenticación implícita no es obligatorio, puede ser mejor usar una conexión HTTPS y alguna forma estándar de autenticación basada en HTML, ya que la autenticación HTTP no soporta "Salir" hasta que el cliente se cierra el navegador web. – Kel

+0

Posible duplicado de [autenticación implícita en Android usando HttpURLConnection] (http://stackoverflow.com/questions/32689185/digest-authentication-in-android-using-httpurlconnection) – ceph3us

Respuesta

5

La autenticación implícita es mucho más compleja que simplemente enviar username:password (que en realidad es autenticación básica ... ¡y la tupla username:password debe estar codificada en Base64!).

Puedes leer todo acerca de digest here.

Si usted no está obligado a usar HttpUrlConnection echar un vistazo a estos dos proyectos:

Ambos ya apoyo Resumen (y otras cosas útiles) de fábrica.

2

HttpURLConnection está bien para trabajos sencillos, pero si quieres algo con funciones más avanzadas (como la autenticación implícita), lo recomiendo Commons HTTP Client.

4

soy capaz de lograr que se haga hábil siguiente código, por favor hágamelo saber si me falta algo;

 DefaultHttpClient httpclient = new DefaultHttpClient(); 

     ResponseHandler<String> responseHandler = new BasicResponseHandler(); 

     httpclient.getCredentialsProvider().setCredentials(
       new AuthScope("localhost", 8080), 
       new UsernamePasswordCredentials("username", "password")); 

     HttpGet httpget = new HttpGet(urlStr); 
     System.out.println("executing request" + httpget.getRequestLine()); 

     String response = httpclient.execute(httpget, responseHandler); 
     System.out.println("Response :: " + response); 
+0

Creo que esto está bien. Usé casi el mismo código. – user485624

+0

DefaultHttpClient en desuso y HttpClient ya no tiene el método getCredentialsProvider ...¿Alguien tiene un ejemplo actualizado? – Rafael

+0

Me funcionó. ¡Gracias! – basari66

3

Usa el siguiente código, funciona.

import org.apache.http.auth.UsernamePasswordCredentials; 
import org.apache.http.client.CredentialsProvider; 
import org.apache.http.impl.client.CloseableHttpClient; 

CredentialsProvider credsProvider = new BasicCredentialsProvider(); 
     credsProvider.setCredentials(
       new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), 
       new UsernamePasswordCredentials(username, password)); 
     CloseableHttpClient httpclient = HttpClients.custom() 
       .setDefaultCredentialsProvider(credsProvider) 
       .build(); 


HttpResponse response = httpClient.execute(get); 
+4

El contexto y la explicación serían útiles para los futuros usuarios que encuentren esta respuesta con el mismo problema – StormeHawke

Cuestiones relacionadas