我'm trying to use a Socks5 proxy server for requests to a certain target (host) that requires proxy in my Java application. I'使用Apache Http库(v.4.5.4) . 我有很多不同的其他目标,不需要代理,因此为整个应用程序设置全局代理不是我的选择 . 所以我为 HttpClient
的某个实例设置了代理 . 代理需要使用login和pass进行身份验证 .
我的解决方案基于此question另外添加认证参数,如documentation中所述 .
这是我的代码:
private void sendSocks5Request(StringEntity requestEntity) throws Exception {
Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new MyConnectionSocketFactory(SSLContexts.createSystemDefault()))
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(reg);
Credentials credentials = new UsernamePasswordCredentials("proxy_user","proxy_pass");
AuthScope authScope = new AuthScope("my.proxy.com", 1080);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(authScope, credentials);
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(cm)
.setDefaultCredentialsProvider(credsProvider)
.build();
try {
InetSocketAddress socksaddr = new InetSocketAddress("my.proxy.com", 1080);
HttpClientContext context = HttpClientContext.create();
context.setAttribute("socks.address", socksaddr);
HttpHost target = new HttpHost("api.telegram.org", 80, "https");
HttpPost request = new HttpPost("/bot<bot_token_here>");
request.setEntity(requestEntity);
System.out.println("Executing request " + request + " to " + target + " via SOCKS proxy " + socksaddr);
CloseableHttpResponse response = httpclient.execute(target, request, context);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
EntityUtils.consume(response.getEntity());
} catch (Exception ex) {
ex.getMessage();
} finally {
response.close();
}
} catch (Exception ex) {
ex.getMessage();
} finally {
httpclient.close();
}
}
代理似乎工作,但我得到一个 Authentication failed
错误 . 代理服务器本身上的日志显示提供的身份验证不包含 proxy_user
用户,而是包含我的计算机的系统用户 . 因此看起来HttpClient忽略了提供的凭据并从系统中获取它 .
我究竟做错了什么?
1 回答
我've spent a few days struggling with the same problem. For me, the simplest way is to use java' s
Authenticator
只需在execute
之前添加此代码:之后,套接字应该发送您的凭据 . 如果您有兴趣,可以调试
java.net.SocksSocketImpl#authenticate(byte, java.io.InputStream, java.io.BufferedOutputStream, long)
方法 .我've tried to use many other methods, but they all don'为我工作 . 我假设
setDefaultCredentialsProvider
正在响应target
上的身份验证,而不是proxy
. 我没有调试那么深 . 我还在试图弄清楚如何更优雅地解决这个问题 . 如果您能找到更好的解决方案,请与我们联系 .