![](/img/trans.png)
[英]How do I use proxy authentication with an SSL connection using HttpsUrlConnection?
[英]How to use HttpsURLConnection through proxy by setProperty?
网络环境:
Https 客户端<==============>代理服务器<==============>Https 服务器
192.168.17.11<-----外网------>192.168.17.22
10.100.21.10<----内网---->10.100.21.11ps:没有默认网关的Http Client,但是可以ping到10.100.21.11
描述:
操作系统:3 台主机上的 Ubuntu 12.04
Https Client:用java(openjdk-6)实现。有一个网络接口。
代理服务器:Apache2.2。有两个网络接口。
Https Server:Tomcat6。有一个网络接口。
我使用两种方法通过代理实现httpsurlconnection :
(为了方便我没有写关于检查serverTrusted和hostnameVerifier问题的ssl句柄函数。如果需要我会更新。)
InetSocketAddress proxyInet = new InetSocketAddress("10.100.21.11",80);
Proxy proxy = new Proxy(Proxy.Type.HTTP, proxyInet);
URL httpsUrl = new URL("https://192.168.17.22:8443/test");
HttpsURLConnection httpsCon = (HttpsURLConnection) httpsUrl.openConnection(proxy);
httpsCon.setDoOutput(true);
httpsCon.setDoInput(true);
httpsCon.setRequestMethod("POST");
OutputStream out = httpsCon.getOutputStream();
OutputStreamWriter owriter = new OutputStreamWriter(out);
owriter.write("<request>test</request>");
owriter.flush();
owriter.close();
...
这种方法可行,我观察到的数据包流也符合我的预期。
HttpClient ---> ProxyServer ---> HttpServer
但是当我使用 set Property 方法时:
System.setProperty("http.proxySet", "true");
System.setProperty("http.proxyHost",10.100.21.11);
System.setProperty("http.proxyPort","80");
URL httpsUrl = new URL("https://192.168.17.22:8443/test");
HttpsURLConnection httpsCon = (HttpsURLConnection)httpsUrl.openConnection();
httpsCon.setDoOutput(true);
httpsCon.setDoInput(true);
httpsCon.setRequestMethod("POST");
OutputStream out = httpsCon.getOutputStream();
OutputStreamWriter owriter = new OutputStreamWriter(out);
owriter.write("<request>test</request>");
owriter.flush();
owriter.close();
...
我收到了NoRouteToHostException: Network is unreachable
。
这让我很困惑。我没有看到 HttpClient 和 ProxyServer 之间的任何数据包。
但是HttpClient可以ping到ProxyServer(10.100.12.10 ping 10.100.21.11)
所以我删除了代理设置(如不使用代理):
还得到了NoRouteToHostException: Network is unreachable
。
我认为这是合理的。因为没有到外网的路由。
我猜这似乎是setProperty方法, httpsUrlConnection的内部函数将检查此 url 是否可以访问。
但这很奇怪。 第一种方法可以成功。
有什么想法吗? 或者第一种和第二种方法有什么不同?
++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++
System.setProperty("https.proxyHost",10.100.21.11);
System.setProperty("https.proxyPort","80");
它可以工作,并且数据包流是我所期望的。
但是设置 https.proxyPort=443 对我不起作用
System.setProperty("https.proxyPort","443");
它会抛出一个异常如下:
java.net.SocketException: Unexpected end of file from server
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:770)
....
所以我认为 Apache Proxy 也必须修改为正确的配置。
您的 URL 连接是 https 而您只设置了 http 代理。
尝试设置 https 代理。
//System.setProperty("https.proxySet", "true");
System.setProperty("https.proxyHost",10.100.21.11);
System.setProperty("https.proxyPort","443");
编辑@EJP 是正确的。 没有 https.proxySet .. 我复制了您的原始问题并包含在答案中。
您需要为它创建一个Proxy
对象。 创建一个如下:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyServer, Integer.parseInt(proxyPort)));
现在使用这个代理来创建HttpURLConnection
对象。
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(proxy);
如果必须为代理设置凭据,请设置Proxy-Authorization
请求属性:
String uname_pwd = proxyUsername + ":" + proxyPassword
String authString = "Basic " + new sun.misc.BASE64Encoder().encode(uname_pwd.getBytes())
connection.setRequestProperty("Proxy-Authorization", authString);
最后,您连接:
connection.connect();
谢谢@divinedragon!
kotlin 上的相同代码:
fun testProxy(login: String, pass: String, proxyData: ProxyData): String {
val url = URL("http://api.ipify.org")
val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress(proxyData.ip, proxyData.port))
val connection = url.openConnection(proxy) as HttpURLConnection
val loginPass = "$login:$pass"
val encodedLoginPass = Base64.getEncoder().encodeToString(loginPass.toByteArray())
val authString = "Basic $encodedLoginPass"
connection.setRequestProperty("Proxy-Authorization", authString);
with(connection) {
requestMethod = "GET" // optional default is GET
connectTimeout = 2000
readTimeout = 2000
return inputStream.bufferedReader().readText()
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.