10

Gracias a este hilo How to download and save a file from Internet using Java? Sé cómo descargar un archivo, ahora mi problema es que necesito autenticarme en el servidor del que estoy descargando. Es una interfaz http para un servidor de subversión. ¿A qué campo debo mirar?Descargar un archivo de Internet usando Java: ¿Cómo autenticar?

Utilizando el código publicado en el último comentario, me sale esta excepción:

java.io.IOException: Server returned HTTP response code: 401 for URL: http://myserver/systemc-2.0.1.tgz 
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1305) 
    at java.net.URL.openStream(URL.java:1009) 
    at mypackage.Installer.installSystemc201(Installer.java:29) 
    at mypackage.Installer.main(Installer.java:38) 

Gracias,

+0

Qué hacer excepción que se obtiene si se omite el identificador de usuario y la contraseña de la url? – cmsjr

+0

es la misma excepción si omito el inicio de sesión/pase o si lo coloco (código 401) – user105413

Respuesta

11

amplía la clase de Authenticator e inscríbete. Los javadocs en el enlace explican cómo.

No sé si esto funciona con el método nio que obtuvo la respuesta aceptada a la pregunta, pero de seguro funciona de la manera antigua que era la respuesta debajo de eso.

Dentro de la implementación de la clase del autenticador, es probable que use un PasswordAuthentication y anule el método getPasswordAuthentication() de su implementación de Authenticator para devolverlo. Esa será la clase a la que se le pasará el nombre de usuario y la contraseña que necesita.

según su petición, aquí es un código de ejemplo:

public static final String USERNAME_KEY = "username"; 
public static final String PASSWORD_KEY = "password"; 
private final PasswordAuthentication authentication; 

public MyAuthenticator(Properties properties) { 
    String userName = properties.getProperty(USERNAME_KEY); 
    String password = properties.getProperty(PASSWORD_KEY); 
    if (userName == null || password == null) { 
     authentication = null; 
    } else { 
     authentication = new PasswordAuthentication(userName, password.toCharArray()); 
    } 
} 

protected PasswordAuthentication getPasswordAuthentication() { 
    return authentication; 
} 

Y lo registre en el método principal (o en algún lugar a lo largo de la línea antes de llamar a la URL):

Authenticator.setDefault(new MyAuthenticator(properties)); 

El el uso es simple, pero la API me parece intrincada y un poco retrógrada a la manera en que normalmente piensas sobre estas cosas. Muy típico del diseño singleton.

+0

¿Podría publicar algún código de muestra? ¡El javadoc no da ningún ejemplo, y es imposible saber cómo usar esta clase realmente! – poundifdef

+3

Bueno, sólo hay que llamar setDefault y eso es todo '\t \t Authenticator.setDefault (nuevo autenticador() { \t \t \t protegida PasswordAuthentication getPasswordAuthentication() { \t \t \t \t retorno nueva PasswordAuthentication ("login"," pasar" .toCharArray()); \t \t \t} \t \t});' estoy tan impresionado – user105413

+0

Eso está muy bien! Una solución java típicamente retorcida. Tenga en cuenta que podría ser más correcto decir que necesita EXTENDER en lugar de IMPLEMENTAR la clase Authenticator; no es una interfaz ... – jsh

1

Ha intentado la construcción de su URL en forma http://user:[email protected]/path?

+0

funciona en mi navegador pero no en mi programa Java – user105413

+0

Lo siento, pero no funcionó. Parece que el Autenticador mencionado por @Yishai envuelve esa técnica http://www.javaworld.com/javaworld/javatips/jw-javatip47.html – cmsjr

7

Este es un código que escribí que busca un sitio web y muestra el contenido en System.out. Se utiliza la autenticación básica:

import java.net.*; 
import java.io.*; 

public class foo { 
    public static void main(String[] args) throws Exception { 

    URL yahoo = new URL("http://www.MY_URL.com"); 

    String passwdstring = "USERNAME:PASSWORD"; 
    String encoding = new 
      sun.misc.BASE64Encoder().encode(passwdstring.getBytes()); 

    URLConnection uc = yahoo.openConnection(); 
    uc.setRequestProperty("Authorization", "Basic " + encoding); 

    InputStream content = (InputStream)uc.getInputStream(); 
    BufferedReader in = 
      new BufferedReader (new InputStreamReader (content)); 

    String line; 
    while ((line = in.readLine()) != null) { 
     System.out.println (line); 
    } 

    in.close(); 
} 

Problemas con el código anterior:

  1. Este código no está listos para la producción (., Pero se pone el punto a través)

  2. Los rendimientos de código esta advertencia del compilador:

 
foo.java:11: warning: sun.misc.BASE64Encoder is Sun proprietary API and may be removed in a future release 
     sun.misc.BASE64Encoder().encode(passwdstring.getBytes()); 
      ^1 warning 

Uno realmente debería usar la clase Autenticador, pero por mi vida, no pude entender cómo y no pude encontrar ningún ejemplo, lo cual demuestra que a la gente de Java no le gusta cuando usa su lenguaje para hacer cosas geniales. :-P

Así que lo anterior no es una buena solución , pero funciona y podría modificarse fácilmente más adelante.

+1

Si quieres un codificador base64, recomiendo la implementación de iharder.net. Dominio público, no puede ser más libre que eso. http://iharder.sourceforge.net/current/java/base64/ – Yishai

+0

Esto es justo lo que necesitaba, gracias. – Amalgovinus

+0

¡Groovy ya tiene soporte para base64! Solo haz passwd.getBytes(). EncodeBase64(). ToString(). Ver http://mrhaki.blogspot.com/2009/11/groovy-goodness-base64-encoding.html –

0

Esta biblioteca de código abierto, http://spnego.sourceforge.net, también tiene algunos ejemplos sobre cómo usar su clase SpnegoHttpURLConnection.

Uno de los constructores en la clase le permite ingresar un nombre de usuario y contraseña.

Eche un vistazo al documento java de la clase para ver los ejemplos.

6

guardar la clase predominante de autenticador:

import java.net.Authenticator; 
import java.net.PasswordAuthentication; 

public class MyAuthenticator extends Authenticator { 
    private static String username = ""; 
    private static String password = ""; 

    protected PasswordAuthentication getPasswordAuthentication() { 
     return new PasswordAuthentication (MyAuthenticator.username, 
       MyAuthenticator.password.toCharArray()); 
    } 

    public static void setPasswordAuthentication(String username, String password) { 
     MyAuthenticator.username = username; 
     MyAuthenticator.password = password; 
    } 
} 

Escribe tu clase principal:

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.Authenticator; 
import java.net.MalformedURLException; 
import java.net.URL; 

public class MyMain{ 


    public static void main(String[] args) { 
     URL url; 
     InputStream is = null; 
     BufferedReader br; 
     String line; 

     // Install Authenticator 
     MyAuthenticator.setPasswordAuthentication("Username", "Password"); 
     Authenticator.setDefault (new MyAuthenticator()); 

     try { 
      url = new URL("Your_URL_Here"); 
      is = url.openStream(); // throws an IOException 
      br = new BufferedReader(new InputStreamReader(is)); 
      while ((line = br.readLine()) != null) { 
       System.out.println(line); 
      } 
     } catch (MalformedURLException mue) { 
      mue.printStackTrace(); 
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } finally { 
      try { 
       if (is != null) is.close(); 
      } catch (IOException ioe) { 
       // nothing to see here 
      } 
     } 

    } 

} 
Cuestiones relacionadas