[英]Why does Apache Commons VFS consider Http Proxy and Socks5 Proxy but simply ignore Socks4 Proxy?
[英]Apache HttpClient Socks5 proxy with authentication
我正在尝试使用Socks5代理服务器来请求对某个目标(主机)的请求,该目标需要Java应用程序中的代理。 我正在使用Apache Http库(4.5.4版)。 我有许多其他不需要代理的目标,因此对我来说,在整个应用程序中全局设置代理不是一个选择。 因此,我为HttpClient
的特定实例设置了代理。 代理要求通过登录和通过身份验证。
这是我的代码:
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会忽略提供的凭据,并从系统中获取它。
我究竟做错了什么?
我花了几天的时间来解决同样的问题。 对我来说,最简单的方法是使用Java的Authenticator
只需在execute
之前添加以下代码:
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(proxyUser, proxyPassword.toCharArray());
}
});
之后,套接字应发送您的凭据。 如果您有兴趣java.net.SocksSocketImpl#authenticate(byte, java.io.InputStream, java.io.BufferedOutputStream, long)
可以调试java.net.SocksSocketImpl#authenticate(byte, java.io.InputStream, java.io.BufferedOutputStream, long)
方法。
我尝试使用许多其他方法,但是它们都不对我有用。 我假设setDefaultCredentialsProvider
正在对target
而不是对proxy
进行身份验证。 我还没有调试那么深。 我仍然试图找出如何更优雅地解决此问题的方法。 让我知道您是否会找到更好的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.