使用Java验证HTTP代理

And*_*ore 56 java proxy http

如何配置用户名和密码以使用Java验证http代理服务器?

我刚刚找到以下配置参数:

http.proxyHost=<proxyAddress>
http.proxyPort=<proxyPort>
https.proxyHost=<proxyAddress>
https.proxyPort=<proxyPort>
Run Code Online (Sandbox Code Playgroud)

但是,我的代理服务器需要身份验证 如何配置我的应用程序以使用代理服务器?

Pas*_*ent 75

(编辑:正如OP指出的那样,使用a java.net.Authenticator也是必需的.为了正确起见,我正在更新我的答案.)

对于身份验证,用于java.net.Authenticator设置代理的配置并设置系统属性http.proxyUserhttp.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);
Run Code Online (Sandbox Code Playgroud)

  • 属性"http.proxyUser"和"http.proxyPassword"不是强制性的.您正在为JVM指定Authenticator.因此,您可以删除这些配置. (3认同)
  • 我也得到了代码片段的响应.但是当我为密码设置了错误的值时,如果请求通过代理,它应该说Connection拒绝.在这种情况下我也得到了输出.如何验证是否通过代理发送请求? (2认同)
  • @Pascal:我认为你的意思是最后两行设置“proxyHost”和“proxyPort”,而不是“proxyUser”和“proxyPassword”,因为后者已经由身份验证器建立。或者我错过了什么? (2认同)

Osc*_*Ryz 32

你几乎就在那里,你只需追加:

-Dhttp.proxyUser=someUserName
-Dhttp.proxyPassword=somePassword
Run Code Online (Sandbox Code Playgroud)


jcs*_*ica 29

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

其他建议使用自定义默认身份验证器.但这很危险,因为这会将密码发送给任何要求的人.

如果某些http/https请求没有通过代理(这很可能取决于配置),这是相关的.在这种情况下,您可以将凭据直接发送到某个http服务器,而不是代理服务器.

他建议以下修复.

// 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;
    }  
});
Run Code Online (Sandbox Code Playgroud)

我还没试过,但它看起来不错.

我稍微修改了原始版本以使用equalsIgnoreCase()而不是equals(host.toLowerCase())因为:http://mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug 和我添加"80"作为端口的默认值,以避免Integer.parseInt(port)中的NumberFormatException.


And*_*dis 17

大多数答案都在那里,但对我来说并不完全.这对我来说对java.net.HttpURLConnection有用(我用JDK 7和JDK 8测试了所有的情况).请注意,您不必使用Authenticator类.

案例1:没有用户身份验证的代理,访问HTTP资源

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport
Run Code Online (Sandbox Code Playgroud)

案例2:使用用户身份验证的代理,访问HTTP资源

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass
Run Code Online (Sandbox Code Playgroud)

案例3:没有用户身份验证的代理,访问HTTPS资源(SSL)

-Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport 
Run Code Online (Sandbox Code Playgroud)

案例4:使用用户身份验证的代理,访问HTTPS资源(SSL)

-Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass
Run Code Online (Sandbox Code Playgroud)

案例5:没有用户身份验证的代理,访问HTTP和HTTPS资源(SSL)

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport 
Run Code Online (Sandbox Code Playgroud)

案例6:使用用户身份验证的代理,访问HTTP和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
Run Code Online (Sandbox Code Playgroud)

您也可以使用System.setProperty("key","value")设置属性.

要访问HTTPS资源,您可能必须通过下载服务器证书并将其保存在信任库中然后使用该信任库来信任该资源.即

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

  • 它在使用 oracle jdk 'ava version "1.8.0_231"' 或 "java version "11.0.5" 2019-10-15 LTS" 的 Linux 上不起作用 被否决,因为我认为在报告的工作测试期间发生了其他事情。(这是Windows特定的东西吗?) (2认同)

And*_*ore 10

但是,仅设置该参数,身份验证不起作用.

有必要添加以下代码:

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());
    }
  }
);
Run Code Online (Sandbox Code Playgroud)


Ant*_*ton 8

对于Java 1.8及更高版本,您必须设置

-Djdk.http.auth.tunneling.disabledSchemes =

使用基本授权代理使用https和Authenticator,如接受的答案中所述

  • 并且计划必须是空的? (2认同)

小智 5

试试我写的这个跑步者。它可能会有所帮助。

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

}
Run Code Online (Sandbox Code Playgroud)