[java] Authenticated HTTP proxy with Java

How can I configure the username and password to authenticate a http proxy server using Java?

I just found the following configuration parameters:

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

But, my proxy server requires authentication. How can I configure my app to use the proxy server?

This question is related to java http proxy

The answer is


Most of the answer is in existing replies, but for me not quite. This is what works for me with java.net.HttpURLConnection (I have tested all the cases with JDK 7 and JDK 8). Note that you do not have to use the Authenticator class.

Case 1 : Proxy without user authentication, access HTTP resources

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

Case 2 : Proxy with user authentication, access HTTP resources

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

Case 3 : Proxy without user authentication, access HTTPS resources (SSL)

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

Case 4 : Proxy with user authentication, access HTTPS resources (SSL)

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

Case 5 : Proxy without user authentication, access both HTTP and HTTPS resources (SSL)

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

Case 6 : Proxy with user authentication, access both HTTP and HTTPS resources (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

You can set the properties in the with System.setProperty("key", "value) too.

To access HTTPS resource you may have to trust the resource by downloading the server certificate and saving it in a trust store and then using that trust store. ie

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

Try this runner I wrote. It could be helpful.

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});
    }

}

You're almost there, you just have to append:

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

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

Other suggest to use a custom default Authenticator. But that's dangerous because this would send your password to anybody who asks.

This is relevant if some http/https requests don't go through the proxy (which is quite possible depending on configuration). In that case, you would send your credentials directly to some http server, not to your proxy.

He suggests the following fix.

// 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;
    }  
});

I haven't tried it yet, but it looks good to me.

I modified the original version slightly to use equalsIgnoreCase() instead of equals(host.toLowerCase()) because of this: http://mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug and I added "80" as the default value for port to avoid NumberFormatException in Integer.parseInt(port).


But, setting only that parameters, the authentication don't works.

Are necessary to add to that code the following:

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());
    }
  }
);

For Java 1.8 and higher you must set

-Djdk.http.auth.tunneling.disabledSchemes=

to make proxies with Basic Authorization working with https along with Authenticator as mentioned in accepted answer


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to http

Access blocked by CORS policy: Response to preflight request doesn't pass access control check Axios Delete request with body and headers? Read response headers from API response - Angular 5 + TypeScript Android 8: Cleartext HTTP traffic not permitted Angular 4 HttpClient Query Parameters Load json from local file with http.get() in angular 2 Angular 2: How to access an HTTP response body? What is HTTP "Host" header? Golang read request body Angular 2 - Checking for server errors from subscribe

Examples related to proxy

Axios having CORS issue Running conda with proxy WebSockets and Apache proxy : how to configure mod_proxy_wstunnel? "Proxy server connection failed" in google chrome Set proxy through windows command line including login parameters Could not resolve all dependencies for configuration ':classpath' Problems using Maven and SSL behind proxy Using npm behind corporate proxy .pac git returns http error 407 from proxy after CONNECT Forwarding port 80 to 8080 using NGINX