2009-10-26 7 views
46

Comment puis-je configurer le nom d'utilisateur et le mot de passe pour authentifier un serveur proxy http à l'aide de Java?Proxy HTTP authentifié avec Java

Je viens de trouver les paramètres de configuration suivants:

http.proxyHost=<proxyAddress> 
http.proxyPort=<proxyPort> 
https.proxyHost=<proxyAddress> 
https.proxyPort=<proxyPort> 

Mais, mon serveur proxy requiert une authentification. Comment puis-je configurer mon application pour utiliser le serveur proxy?

+2

Quel type d'authentification votre serveur proxy accepte-t-il? De base, Digest ou NTLM? – brianegge

Répondre

65

(EDIT:.. Comme l'a souligné l'OP, l'utilisation d'un java.net.Authenticator est nécessaire aussi je mettre à jour ma réponse en conséquence pour le bien de justesse)

Pour l'authentification, utilisez java.net.Authenticator pour définir la configuration de proxy et Définissez les propriétés système http.proxyUser et http.proxyPassword.

final String authUser = "user"; 
final String authPassword = "password"; 
Authenticator.setDefault(
    new Authenticator() { 
     @Override 
     public PasswordAuthentication getPasswordAuthentication() { 
     return new PasswordAuthentication(
       authUser, authPassword.toCharArray()); 
     } 
    } 
); 

System.setProperty("http.proxyUser", authUser); 
System.setProperty("http.proxyPassword", authPassword); 
+2

J'ai aussi reçu la réponse avec l'extrait de code. Mais quand je place les mauvaises valeurs pour le mot de passe, si la demande a traversé le proxy, il devrait dire Connexion refusée. J'ai eu la sortie dans ce cas aussi. Comment puis-je vérifier si les demandes sont envoyées via le proxy ??? – divinedragon

+0

@Pascal: Je pense que vous vouliez dire ces deux dernières lignes pour définir 'proxyHost' et' proxyPort', pas 'proxyUser' et' proxyPassword', car ces derniers sont déjà établis par l'Authenticator. Ou est-ce que je manque quelque chose? –

+0

@divinedragon Il ne faut pas dire 'connexion refusée'. Ce n'est même pas possible. La connexion a été acceptée par TCP, au proxy, qui a ensuite échoué votre authentification. À ce stade, il est impossible pour le proxy de générer un refus de connexion. – EJP

23

Vous y êtes presque, il vous suffit d'ajouter:

-Dhttp.proxyUser=someUserName 
-Dhttp.proxyPassword=somePassword 
10

Mais, seul réglage des paramètres, l'authentification ne fonctionne pas.

sont nécessaires pour ajouter à ce code les éléments suivants:

final String authUser = "myuser"; 
final String authPassword = "secret"; 

System.setProperty("http.proxyHost", "hostAddress"); 
System.setProperty("http.proxyPort", "portNumber"); 
System.setProperty("http.proxyUser", authUser); 
System.setProperty("http.proxyPassword", authPassword); 

Authenticator.setDefault(
    new Authenticator() { 
    public PasswordAuthentication getPasswordAuthentication() { 
     return new PasswordAuthentication(authUser, authPassword.toCharArray()); 
    } 
    } 
); 
+0

Vous n'avez pas besoin d'ajouter l'authentificateur. Pour moi, avec Java 7 et Java 8, il suffit de définir les propriétés http. *. –

3

Essayez ce coureur je l'ai écrit. Cela pourrait être utile.

import java.io.InputStream; 
import java.lang.reflect.Method; 
import java.net.Authenticator; 
import java.net.PasswordAuthentication; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.Scanner; 

public class ProxyAuthHelper { 

    public static void main(String[] args) throws Exception { 
     String tmp = System.getProperty("http.proxyUser", System.getProperty("https.proxyUser")); 
     if (tmp == null) { 
      System.out.println("Proxy username: "); 
      tmp = new Scanner(System.in).nextLine(); 
     } 
     final String userName = tmp; 

     tmp = System.getProperty("http.proxyPassword", System.getProperty("https.proxyPassword")); 
     if (tmp == null) { 
      System.out.println("Proxy password: "); 
      tmp = new Scanner(System.in).nextLine(); 
     } 
     final char[] password = tmp.toCharArray(); 

     Authenticator.setDefault(new Authenticator() { 
      @Override 
      protected PasswordAuthentication getPasswordAuthentication() { 
       System.out.println("\n--------------\nProxy auth: " + userName); 
       return new PasswordAuthentication (userName, password); 
      } 

     }); 

     Class<?> clazz = Class.forName(args[0]); 
     Method method = clazz.getMethod("main", String[].class); 
     String[] newArgs = new String[args.length - 1]; 
     System.arraycopy(args, 1, newArgs, 0, newArgs.length); 
     method.invoke(null, new Object[]{newArgs}); 
    } 

} 
26

http://rolandtapken.de/blog/2012-04/java-process-httpproxyuser-and-httpproxypassword dit:

Autre suggèrent d'utiliser un authentificateur par défaut personnalisé. Mais c'est dangereux car cela enverrait votre mot de passe à quiconque le demande.

Ceci est pertinent si certaines requêtes http/https ne passent pas par le proxy (ce qui est tout à fait possible en fonction de la configuration). Dans ce cas, vous enverrez vos informations d'identification directement à un serveur http, pas à votre proxy.

Il suggère le correctif suivant.

// Java ignores http.proxyUser. Here come's the workaround. 
Authenticator.setDefault(new Authenticator() { 
    @Override 
    protected PasswordAuthentication getPasswordAuthentication() { 
     if (getRequestorType() == RequestorType.PROXY) { 
      String prot = getRequestingProtocol().toLowerCase(); 
      String host = System.getProperty(prot + ".proxyHost", ""); 
      String port = System.getProperty(prot + ".proxyPort", "80"); 
      String user = System.getProperty(prot + ".proxyUser", ""); 
      String password = System.getProperty(prot + ".proxyPassword", ""); 

      if (getRequestingHost().equalsIgnoreCase(host)) { 
       if (Integer.parseInt(port) == getRequestingPort()) { 
        // Seems to be OK. 
        return new PasswordAuthentication(user, password.toCharArray()); 
       } 
      } 
     } 
     return null; 
    } 
}); 

Je ne l'ai pas encore essayé, mais ça me semble bon.

J'ai modifié la version originale légèrement à utiliser equalsIgnoreCase() au lieu d'égal à égal (host.toLowerCase()) à cause de cela: http://mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug et j'ajouté « 80 » comme valeur par défaut pour le port pour éviter NumberFormatException dans Integer.parseInt (Port).

7

La plupart des réponses sont là, mais pour moi pas tout à fait. C'est ce qui fonctionne pour moi avec java.net.HttpURLConnection (j'ai testé tous les cas avec JDK 7 et JDK 8). Notez que vous n'avez pas besoin d'utiliser la classe Authenticator.

Cas 1: Proxy sans authentification de l'utilisateur, les ressources HTTP d'accès

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport 

Cas 2: Proxy avec authentification de l'utilisateur, l'accès aux ressources HTTP

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass 

Cas 3: Proxy sans authentification de l'utilisateur, l'accès HTTPS ressources (SSL)

-Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport 

Cas 4: Proxy avec l'utilisateur au thentication, les ressources HTTPS d'accès (SSL)

-Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass 

Cas 5: Proxy sans authentification de l'utilisateur, accès à la fois les ressources HTTP et HTTPS (SSL)

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport 

Cas 6: Proxy avec authentification de l'utilisateur, l'accès HTTP et les ressources HTTPS (SSL)

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttp.proxyUser=myuser -Dhttp.proxyPassword=mypass -Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass 

Vous pouvez définir les propriétés du System.setProperty avec ("clé", « valeur) aussi.

Pour accéder à la ressource HTTPS, il se peut que vous deviez faire confiance à la ressource en téléchargeant le certificat de serveur et en l'enregistrant dans un fichier de clés certifiées, puis en utilisant ce fichier de clés. à savoir

System.setProperty("javax.net.ssl.trustStore", "c:/temp/cert-factory/my-cacerts"); 
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 
+1

Je peux confirmer que l'utilisation de la classe Authenticator n'est pas requise sur JDK 7 ou 8. Il suffit d'utiliser '-D .proxyUser =' et '-D .proxyPassword ='. –

+0

Merci pour l'édition @Cristiano –

1

Pour Java 1.8 et plus vous devez définir

-Djdk.http.auth.tunneling.disabledSchemes =

pour faire des procurations avec le travail de base Autorisation par https avec Authentificateur mentionné dans la réponse acceptée