使用 Java 进行身份验证的 HTTP 代理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1626549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Authenticated HTTP proxy with Java
提问by Andre Pastore
How can I configure the username and password to authenticate a http proxy server using Java?
如何配置用户名和密码以使用 Java 对 http 代理服务器进行身份验证?
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?
但是,我的代理服务器需要身份验证。如何配置我的应用程序以使用代理服务器?
采纳答案by Pascal Thivent
(EDIT: As pointed out by the OP, the using a java.net.Authenticator
is required too. I'm updating my answer accordingly for the sake of correctness.)
(编辑:正如 OP 所指出的,使用 ajava.net.Authenticator
也是必需的。为了正确起见,我正在相应地更新我的答案。)
(EDIT#2: As pointed out in another answer, in JDK 8 it's required to remove basic
auth scheme from jdk.http.auth.tunneling.disabledSchemes
property)
(编辑#2:正如在另一个答案中指出的,在 JDK 8 中需要basic
从jdk.http.auth.tunneling.disabledSchemes
属性中删除身份验证方案)
For authentication, use java.net.Authenticator
to set proxy's configuration and set the system properties http.proxyUser
and http.proxyPassword
.
对于身份验证,用于java.net.Authenticator
设置代理的配置并设置系统属性http.proxyUser
和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);
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
回答by OscarRyz
You're almost there, you just have to append:
你快到了,你只需要附加:
-Dhttp.proxyUser=someUserName
-Dhttp.proxyPassword=somePassword
回答by Andre Pastore
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());
}
}
);
回答by MichealKum
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});
}
}
回答by jcsahnwaldt says GoFundMonica
http://rolandtapken.de/blog/2012-04/java-process-httpproxyuser-and-httpproxypasswordsays:
http://rolandtapken.de/blog/2012-04/java-process-httpproxyuser-and-httpproxypassword说:
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.
如果某些 http/https 请求不通过代理(这很可能取决于配置),这是相关的。在这种情况下,您会将您的凭据直接发送到某个 http 服务器,而不是您的代理。
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-bugand I added "80" as the default value for port to avoid NumberFormatException in Integer.parseInt(port).
我稍微修改了原始版本以使用 equalsIgnoreCase() 而不是 equals(host.toLowerCase()) 因为这个:http://mattryall.net/blog/2009/02/the-inavour-turkish-locale-bug和我添加了“80”作为端口的默认值,以避免在 Integer.parseInt(port) 中出现 NumberFormatException。
回答by Andreas Panagiotidis
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.
大多数答案都在现有答复中,但对我来说并不完全。这就是 java.net.HttpURLConnection 对我有用的方法(我已经用 JDK 7 和 JDK 8 测试了所有情况)。请注意,您不必使用 Authenticator 类。
Case 1 : Proxy without user authentication, access HTTP resources
案例一:代理无需用户认证,访问HTTP资源
-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport
Case 2 : Proxy with user authentication, access HTTP resources
案例二:代理用户认证,访问HTTP资源
-Dhttp.proxyHost=myproxy -Dhttp.proxyPort=myport -Dhttps.proxyUser=myuser -Dhttps.proxyPassword=mypass
Case 3 : Proxy without user authentication, access HTTPS resources (SSL)
案例三:代理无需用户认证,访问HTTPS资源(SSL)
-Dhttps.proxyHost=myproxy -Dhttps.proxyPort=myport
Case 4 : Proxy with user authentication, access HTTPS resources (SSL)
案例 4:使用用户身份验证的代理,访问 HTTPS 资源 (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)
案例 5:代理无需用户认证,同时访问 HTTP 和 HTTPS 资源(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)
案例 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
You can set the properties in the with System.setProperty("key", "value) too.
您也可以在 with System.setProperty("key", "value) 中设置属性。
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
要访问 HTTPS 资源,您可能必须通过下载服务器证书并将其保存在信任库中,然后使用该信任库来信任该资源。IE
System.setProperty("javax.net.ssl.trustStore", "c:/temp/cert-factory/my-cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
回答by Anton
For Java 1.8 and higher you must set
对于 Java 1.8 及更高版本,您必须设置
-Djdk.http.auth.tunneling.disabledSchemes=
-Djdk.http.auth.tunneling.disabledSchemes=
to make proxies with Basic Authorization working with https along with Authenticator as mentioned in accepted answer
如接受的答案中所述,使用基本授权与 https 以及身份验证器一起使用代理