Link to home
Start Free TrialLog in
Avatar of Professor
Professor

asked on

Apache Jakarta ProxyClient problem

I am trying to use the org.apache.commons.httpclient.ProxyClient class to tunnel our applications protocol through a http proxy.

However for some reason this does not work correctly and all i keep getting is a 403 forbidden error, most likely from the proxy.

The proxy I use for testing is squid/2.5.STABLE13-NT (Windows XP port) configured for basic authentication using win32_auth.

CODE:

package de.symmedia.webclient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.ProxyClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthPolicy;
import org.apache.commons.httpclient.auth.AuthScope;

public class TestProxyConnection {

      public static void main(String[] args) {
            
            ProxyClient client = new ProxyClient();
            
            HostConfiguration config = client.getHostConfiguration();
            
            config.setHost("www.google.de");
            
            config.setProxy("thor", 8128);
            
        // This is to make HttpClient pick the Basic authentication scheme over NTLM & Digest
        List authPrefs = new ArrayList(3);
        authPrefs.add(AuthPolicy.BASIC);
//        client.getParams().setAuthenticationPreemptive(true);
        client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
            
            HttpState httpState = client.getState();
            
            AuthScope scope = new AuthScope("192.168.1.132",8128,AuthScope.ANY_REALM,AuthScope.ANY_SCHEME);
            
            UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("administrator","password");
            
            httpState.setProxyCredentials(scope, credentials);

            ProxyClient.ConnectResponse response;
            
            try {
                  response = client.connect();
                  
                  if ( response.getSocket() != null ) {
                        Socket socket = response.getSocket();      
                        try {
                              OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream(), "ISO-8859-1");
                   
                              out.write("GET http://www.google.de/ HTTP/1.1\r\n");  
                    out.write("Host: www.google.de\r\n");  
                    out.write("Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)\r\n");  
                    out.write("\r\n");  
                    out.flush();
                   
                    BufferedReader in = new BufferedReader(
                        new InputStreamReader(socket.getInputStream(), "ISO-8859-1"));
                   
                    String line = null;
                    while ((line = in.readLine()) != null) {
                        System.out.println(line);
                    }      
                        } finally {
                              socket.close();
                        }
                  } else {
                  // the proxy connect was not successful, check connect method for reasons why
                  System.out.println("Connect failed: " + response.getConnectMethod().getStatusLine());
                  System.out.println(response.getConnectMethod().getResponseBodyAsString());
                  }

            } catch (HttpException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            } catch (IOException e) {
                  // TODO Auto-generated catch block
                  e.printStackTrace();
            }
            
            
            
      }
      
}


I would be very grateful for some quick help.

Thank you in advance everybody.
Avatar of Mayank S
Mayank S
Flag of India image

>> UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("administrator","password");

Is this a domain account or a local system account? Try with a domain account with and without the "DOMAIN_NAME\" prefix in the user-name.
Avatar of Professor
Professor

ASKER

It is a local system account. I have also tried other accounts on the system as well as domain accounts.
Can you authenticate through your browser when you set its proxy to Squid?
No need to try local accounts. You should use domain accounts because I guess they will be the ones authenticated on the proxy-server.
The same credentials do actually work when using squid as a proxy for firefox. Same local credentials.
This is what the squid log says:

1144247192.584     16 192.168.1.23 TCP_DENIED/403 1451 CONNECT www.google.de:80 - NONE/- text/html
Why don't you just directly set the http.proxyHost/Port system properties?
>> The same credentials do actually work when using squid as a proxy for firefox.

Did you check test with the same URL?
There was some reason for not setting the system properties ... however right now i cannot think of one. i was just told to do it the way i do it ... i think it might be something about the supported authentication types, the dynamic configurability and the fact that it does not necessarily need to be a http proxy, it might be socks too.

I just noticed something: When using IE, i cannot actually log in with the credentials i was using.
sorry, appears to be some sort of IE7 problem ...
the IE not working i mean ...
Personally i would do the following:

a. set the proxy directly unless there's a *good* reason for not doing
b. make sure you can authenticate with 'ready made' clients first
>> however right now i cannot think of one

Then did you try with them now?
There is DEFINITELY a good reason for using the apache httpclient; therefore i do not really see the point in even trying the system properties.

I tried with most clients i have here and also with the example that comes with the httpclient. The ready made clients like IE6, Firefox etc. all work, but even the example coming with the httpclient library does not work. :/
>>There is DEFINITELY a good reason for using the apache httpclient

There's some confusion here. It doesn't mean you have to abandon using HttpClient. It just means you don't have to write proxying code - all you need to do is write standard client code
>>  therefore i do not really see the point in even trying the system properties.

You weren't told to remove everything else that you have there. Just the part for setting the proxy - set it in the system properties.
I just talked with the lead developer again and there IS a very good reason for not using the system properties :) Sorry for the confusion. The problem is that when we use the system properties, _all_ sockets created will be proxied; however we need to have control over which sockets use the proxy and which dont.
>>however we need to have control over which sockets use the proxy and which dont.

OK, but AFAICS there's still no need to be writing raw http over sockets. Shall look into it
...although:

>>to tunnel our applications protocol

what exactly do you mean here?
The raw ftp isnt really the issue here; thats just in there for testing. The actual point of the testing is to get our applications TCP based protocol tunneled through an http proxy:

client :: proxy :: internet :: server :: proxy :: internet :: central server

which is necessary for some of our customers' network architectures.

Therefore right now i am testing around trying to find out what the most effective way is to tunnel our protocol through an http based proxy. SOCKS implementations are all ready and functional; only the http based proxy implementation is currently based on raw http code AND additionally only working for basic authentication. I am trying to find a way to allow the application to authenticate against basic and digest as well as ntlm based proxies like MS ISA Server.

I hope this clarifies the situation a little bit :)
It appears that I have solved the issue.

The problem was that the ProxyClient only authenticates against the proxy server proxyclient.getParams().setAuthenticationPreemptive(true); is set.
Great. Looks like you can get a PAQ/ Refund.
ASKER CERTIFIED SOLUTION
Avatar of GranMod
GranMod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial