1

I'm trying to use a Socks5 proxy server for requests to a certain target (host) that requires proxy in my Java application. I'm using Apache Http library (v. 4.5.4). I have lots of different other targets which do not require proxy, so setting up proxy globally for the whole application is not an option for me. So i set up proxy for a certain instance of HttpClient. The proxy requires authentication with login and pass.

My solution is based on this question additionally adding authentication parameters as described in documentation.

Here is my code:

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();
        }
}

Proxy seems to work, but i get a Authentication failed error. Logs on the proxy server itself show that provided authentication contains not the proxy_user user, but my machine's system user. So it seems like HttpClient ignores provided credentials and takes it from the system.

What am i doing wrong?

Emptyfruit
  • 303
  • 2
  • 11
  • We have the same issue, the proxy we are using does not require authentication but since our java code is essentially sending the system user (which is actually a security concern since it offers information the target system does not need!!!) the proxy throws an error which causes the whole communication to fail. Did you make any way? It seems this question is the only one that tackles this issue! – DJGummikuh Nov 09 '18 at 08:54

1 Answers1

1

I've spent a few days struggling with the same problem. For me, the simplest way is to use java's Authenticator Just add this code before execute:

Authenticator.setDefault(new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(proxyUser, proxyPassword.toCharArray());
    }
});

After that, a socket should send your credentials. You may debug the java.net.SocksSocketImpl#authenticate(byte, java.io.InputStream, java.io.BufferedOutputStream, long) method if you have an interest.

I've tried to use many other methods, but they all don't work for me. I assume that setDefaultCredentialsProvider is responding for authentication on the target, not on the proxy. I didn't debug so deep yet. I still trying to figure out how to solve this problem more elegant. Let me know if you will find a better solution.

I V
  • 123
  • 2
  • 8