- 42
- 0
在代码里已经设置了conn.setRequestProperty("Proxy-Authorization", auth);但这个设置只对正式的请求有效,通过wireshark发现在发出正式请求前,会先发出一个CONNECT请求来建立Tunnel,而这个CONNECT请求是没有设置Proxy-Authorization请求头的,导致应答返回407.通过分析源码找到如下代码段:
private void setPreemptiveProxyAuthentication(MessageHeader requests) throws IOException {
AuthenticationInfo pauth
= AuthenticationInfo.getProxyAuth(http.getProxyHostUsed(),
http.getProxyPortUsed());
if (pauth != null && pauth.supportsPreemptiveAuthorization()) {
String value;
if (pauth instanceof DigestAuthentication) {
DigestAuthentication digestProxy = (DigestAuthentication) pauth;
if (tunnelState() == TunnelState.SETUP) {
value = digestProxy
.getHeaderValue(connectRequestURI(url), HTTP_CONNECT);
} else {
value = digestProxy.getHeaderValue(getRequestURI(), method);
}
} else {
value = pauth.getHeaderValue(url, method);
}
// Sets "Proxy-authorization"
requests.set(pauth.getHeaderName(), value);
currentProxyCredentials = pauth;
}
}
会有一个缓存来根据proxyHost和proxyPort来缓存其验证信息,但不知道这个验证信息该如何正确设置。继续分析源码,再第一次请求失败后会判断是否为407,如果是的话会通过Authenticator获取用户名密码信息并缓存,这样似乎可以通过
Authenticator authenticator = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return (new PasswordAuthentication("admin", "Admin@2018!".toCharArray()));
}
};
Authenticator.setDefault(authenticator);
来设置用户名和密码,发送第一次的时候回返回407,然后根据应答和Authenticator创建并缓存验证信息,那么第二次应该会成功,但是如下的测试代码两次全都失败了
public static void main(String[] a) {
Authenticator authenticator = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
return (new PasswordAuthentication("admin", "admin".toCharArray()));
}
};
Authenticator.setDefault(authenticator);
try {
testSend();
} catch (KeyManagementException | NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
try {
testSend();
} catch (KeyManagementException | NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
}
private static void testSend() throws KeyManagementException, NoSuchAlgorithmException, IOException {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] { new DisabledValidationTrustManager() }, null);
SSLSocketFactory sslFactory = sslContext.getSocketFactory();
Proxy proxy = new Proxy(Type.HTTP, new InetSocketAddress("host", port));
String auth = "Basic " + Base64.getEncoder().encodeToString("admin:admin".getBytes());
URL url = new URL("https://www.baidu.com");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(proxy);
conn.setRequestProperty("Proxy-Authorization", auth);
conn.setDoInput(true);
conn.setHostnameVerifier((v1, v2) -> true);
conn.setSSLSocketFactory(sslFactory);
conn.setRequestMethod("GET");
conn.connect();
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
conn.disconnect();
}
因为这写代码并没有开源,所以无法debug,以上只能通过观察分析,在网上找了半天使用方法也没有找到,不知道有没有人知道这个要怎么使用?
- 共 0 条
- 全部回答
-
捉鳖 普通会员 1楼
在使用HTTPSURLConnection通过代理访问时,你可以通过以下步骤设置Proxy-Authorization:
-
首先,你需要获取到你的代理服务器的URL。这通常可以在你的代理服务器的设置中找到。
-
然后,你需要将你的代理服务器的URL添加到HTTPSURLConnection的代理列表中。这可以通过设置
setProxyHost方法来实现。
java URL url = new URL("http://proxy.example.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("Proxy-Host", "proxy.example.com"); connection.setRequestProperty("Proxy-User-Agent", "Mozilla/5.0"); connection.setRequestProperty("Proxy-Port", "8080");注意,你需要将"proxy.example.com"替换为你的代理服务器的URL。
- 如果你希望HTTP请求自动转换为HTTPS请求,你可以设置
setDoOutput方法为true。
java connection.setRequestProperty("Proxy-Do-Output", "true");- 最后,你需要创建一个HTTPSURLConnection对象并使用它来访问服务器。
java URL url = new URL("https://example.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("User-Agent", "Mozilla/5.0"); connection.setRequestProperty("Accept-Encoding", "gzip, deflate"); connection.setRequestProperty("Proxy-Authorization", "Basic " + Base64.getEncoder().encodeToString(((Proxyunnel) proxy).getCredentials()));在这个例子中,我们使用了一个名为
Proxyunnel的代理类来设置代理。这个类的构造函数接受一个代理服务器的URL和一个用户的密码。注意:这个例子假设你已经在你的代理服务器上设置了一个名为"Proxy-Authorization"的字段,其中包含一个包含用户名和密码的字符串。你需要将"Basic " + Base64.getEncoder().encodeToString(((Proxyunnel) proxy).getCredentials()))替换为你的代理服务器的实际值。
-
- 扫一扫访问手机版
回答动态

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器更新之后。服务器里面有部分玩家要重新创建角色是怎么回事啊?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题函数计算不同地域的是不能用内网吧?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题ARMS可以创建多个应用嘛?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题在ARMS如何申请加入公测呀?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题前端小程序接入这个arms具体是如何接入监控的,这个init方法在哪里进行添加?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器刚到期,是不是就不能再导出存档了呢?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器的游戏版本不兼容 尝试更新怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器服务器升级以后 就链接不上了,怎么办?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器转移以后服务器进不去了,怎么解决?预计能赚取 0积分收益

- 神奇的四哥:发布了悬赏问题阿里云幻兽帕鲁服务器修改参数后游戏进入不了,是什么情况?预计能赚取 0积分收益
- 回到顶部
- 回到顶部

