使用Java进行身份验证的HTTP代理

使用Java进行身份验证的HTTP代理,java,http,proxy,Java,Http,Proxy,如何配置用户名和密码以使用Java对http代理服务器进行身份验证 我刚刚找到以下配置参数: http.proxyHost=<proxyAddress> http.proxyPort=<proxyPort> https.proxyHost=<proxyAddress> https.proxyPort=<proxyPort> http.proxyHost= http.proxyPort= https.proxyHost= https.proxyPo

如何配置用户名和密码以使用Java对http代理服务器进行身份验证

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

http.proxyHost=<proxyAddress>
http.proxyPort=<proxyPort>
https.proxyHost=<proxyAddress>
https.proxyPort=<proxyPort>
http.proxyHost=
http.proxyPort=
https.proxyHost=
https.proxyPort=
但是,我的代理服务器需要身份验证。如何将我的应用程序配置为使用代理服务器?

(编辑:正如OP所指出的,还需要使用
java.net.Authenticator
。为了正确起见,我正在相应地更新我的答案。)

(编辑#2:如中所指出的,在JDK 8中,需要从
JDK.http.auth.tunneling.disabledSchemes
属性中删除
basic
auth方案)

对于身份验证,请使用
java.net.Authenticator
设置代理的配置,并设置系统属性
http.proxyUser
http.proxyPassword

最终字符串authUser=“user”;
最后一个字符串authPassword=“password”;
Authenticator.setDefault(
新验证器(){
@凌驾
公共密码身份验证getPasswordAuthentication(){
返回新的PasswordAuthentication(authUser,authPassword.toCharray());
}
}
);
System.setProperty(“http.proxyUser”,authUser);
System.setProperty(“http.proxyPassword”,authPassword);
setProperty(“jdk.http.auth.tunneling.disabledSchemes”,”);

您就快到了,只需附加:

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

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

需要在该代码中添加以下内容:

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

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

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

}
import java.io.InputStream;
导入java.lang.reflect.Method;
导入java.net.Authenticator;
导入java.net.PasswordAuthentication;
导入java.net.URL;
导入java.net.URLConnection;
导入java.util.Scanner;
公共类ProxyAuthHelper{
公共静态void main(字符串[]args)引发异常{
字符串tmp=System.getProperty(“http.proxyUser”,System.getProperty(“https.proxyUser”);
if(tmp==null){
System.out.println(“代理用户名:”);
tmp=新扫描仪(System.in).nextLine();
}
最终字符串userName=tmp;
tmp=System.getProperty(“http.proxyPassword”,System.getProperty(“https.proxyPassword”);
if(tmp==null){
System.out.println(“代理密码:”);
tmp=新扫描仪(System.in).nextLine();
}
final char[]password=tmp.toCharArray();
setDefault(新验证器(){
@凌驾
受保护的密码身份验证getPasswordAuthentication(){
System.out.println(“\n----------------\n验证:“+用户名”);
返回新密码身份验证(用户名、密码);
}
});
Class clazz=Class.forName(args[0]);
方法Method=clazz.getMethod(“main”,String[].class);
字符串[]newArgs=新字符串[args.length-1];
数组复制(args,1,newArgs,0,newArgs.length);
调用(null,新对象[]{newArgs});
}
}
说:

其他建议使用自定义默认验证器。但这很危险,因为这会将你的密码发送给任何询问的人

如果某些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;
    }  
});
我还没试过,但我觉得不错


我稍微修改了原始版本,使用equalsIgnoreCase()而不是equals(host.toLowerCase()),因为:我添加了“80”作为端口的默认值,以避免Integer.parseInt(port)中出现NumberFormatException。

大多数答案都在现有的回复中,但对我来说并不完全正确。这就是我在java.net.HttpURLConnection中的工作原理(我已经用JDK 7和JDK 8测试了所有案例)。请注意,您不必使用Authenticator类

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

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport
-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass
案例2:具有用户身份验证的代理,访问HTTP资源

-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport
-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass
案例3:无用户身份验证的代理,访问HTTPS资源(SSL)

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

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

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

您也可以使用System.setProperty(“键”、“值”)在中设置属性

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

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

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

-Djdk.http.auth.tunneling.disabledSchemes=


要使具有基本授权的代理与https以及accepted answer中提到的Authenticator一起工作,代理服务器接受/需要什么样的身份验证?Basic、Digest或NTLM?我也收到了带有代码段的响应。但是,当我为密码设置了错误的值时,如果请求通过代理,则应该说连接被拒绝。在这种情况下,我也得到了输出。我如何验证请求是否通过代理发送???@Pascal:我想你指的是最后两行设置
proxyHost
proxyPort
,而不是
proxyUser
proxyPassword
,因为后者已经由作者建立cator.还是我遗漏了什么?@divinedragon它不应该说“连接被拒绝”。这甚至是不可能的。TCP接受了到代理的连接,然后代理的身份验证失败。此时代理不可能生成连接拒绝。属性“http.proxyUser”和“http.proxyPassword”“不是强制性的。您正在指定身份验证
-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttp.proxyUser=myuser -Dhttp.proxyPassword=mypass -Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass
 System.setProperty("javax.net.ssl.trustStore", "c:/temp/cert-factory/my-cacerts");
 System.setProperty("javax.net.ssl.trustStorePassword", "changeit");