web-dev-qa-db-fra.com

Proxy HTTP authentifié avec Java

Comment configurer le nom d'utilisateur et le mot de passe pour authentifier un serveur proxy http à l'aide de 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 nécessite une authentification. Comment configurer mon application pour utiliser le serveur proxy?

56
Andre Pastore

(EDIT: Comme l’a souligné le PO, l’utilisation d’un Java.net.Authenticator est requis aussi. J'actualise ma réponse en conséquence pour des raisons de rectitude.)

Pour l'authentification, utilisez Java.net.Authenticator pour définir la configuration du proxy et définir les propriétés du 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);
74
Pascal Thivent

Vous y êtes presque, il vous suffit de joindre:

-Dhttp.proxyUser=someUserName
-Dhttp.proxyPassword=somePassword
32
OscarRyz

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

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

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 enverriez vos informations d'identification directement à un serveur http, et non à 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 n'ai pas encore essayé, mais ça me semble bien.

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

29
jcsahnwaldt

La plupart des réponses se trouvent dans les réponses existantes, mais pas tout à fait pour moi. C'est ce qui fonctionne pour moi avec Java.net.HttpURLConnection (j'ai testé tous les cas avec JDK 7 et JDK 8). Notez qu'il n'est pas nécessaire d'utiliser la classe Authenticator.

Cas 1: proxy sans authentification de l'utilisateur, accès aux ressources HTTP

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

Cas 2: proxy avec authentification d'utilisateur, accès aux ressources HTTP

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

Cas 3: proxy sans authentification d'utilisateur, accédez aux ressources HTTPS (SSL)

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

Cas 4: proxy avec authentification d'utilisateur, accès aux ressources HTTPS (SSL)

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

Cas 5: proxy sans authentification d'utilisateur, accédez aux ressources HTTP et HTTPS (SSL)

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

Cas 6: proxy avec authentification d'utilisateur, accédez aux ressources HTTP et 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 également définir les propriétés dans avec System.setProperty ("clé", "valeur).

Pour accéder à une ressource HTTPS, vous devrez peut-être faire confiance à la ressource en téléchargeant le certificat de serveur et en l'enregistrant dans un magasin de confiance, puis en utilisant ce magasin. c'est à dire

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

Mais, en ne définissant que ces 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());
    }
  }
);
10
Andre Pastore

Pour Java 1.8 et supérieur, vous devez définir

-Djdk.http.auth.tunneling.disabledSchemes =

faire des proxies avec une autorisation de base en utilisant https avec Authenticator comme mentionné dans la réponse acceptée

8
Anton

Essayez ce coureur que j'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});
    }

}
4
MichealKum