On Tue, 2006-10-31 at 12:51 -0800, Jeff Ling wrote:
> Hello,
> 
> I have been using httpclient for a while. However, just recently I have run
> into two customers that have some kind of issues. To simplify the situation,
> I've written a very simple method to test it out. Here is the first issue:
> if the username/password are not correct, or if the user does not have
> authorization to access that url on the IIS 6.0 site, it enters into an
> infinite loop. I am using version 3.0.1.
> 

Jeff,

You are not using the CredentialsProvider interface correctly

(Copied from the CredentialsProvider javadocs)
------------
HttpClient makes no provisions to check whether the same credentials
have been tried already. It is a responsibility of the custom
credentials provider to keep track of authentication attempts and to
ensure that credentials known to be invalid are not retried. HttpClient
will simply store the set of credentials returned by the custom
credentials provider in the HttpState object and will attempt to use
these credentials for all subsequent requests with the given
authentication scope.
------------

I admit CredentialsProvider is rather difficult to use for anything but
interactive authentication (which it was intended for in the first
place) for which I take full responsibility. CredentialsProvider is
likely to change drastically in HttpClient 4.0

Oleg

> I've traced the source code. It seems that the problem is in
> HttpMethodDirector:
> 
>             for (int redirectCount = 0;;) { //big loop
>                 authenticate(method);  //send out authentication request
>                 executeWithRetry(method); //send out message body
>   ...
>                 boolean retry = false;
>   ...
>                 if (isAuthenticationNeeded(method)) {  // NTLM returns 401
> in handshake process, or when not authorized
>                     if (processAuthenticationResponse(method)) {
>                         LOG.debug("Retry authentication");
>                         retry = true; //now retry becomes true
>                     }
>                 }
>                 if (!retry) { //it wouldn't break
>                     break;
>                 }
>  ...
> 
> 
> The problem (I think) is that even in the NTLM normal handshake process, 401
> code is returned, so isAuthenticationNeeded() returns true. This is fine
> because when it finishes the handshake process, isAuthenticationNeeded()
> returns false. However, if the user name /password are wrong, or the user
> doesn't have access to the web resource, 401 code will also be returned.
> Since this code uses a loop instead of following/verifying the NTLM
> handshake process, it just keeps retrying until connection times out.
> 
> Not sure whether this explaination is correct. I would assume that NTLM is
> so widely used that there shouldn't be a problem like this. Am I missing
> something? Here is how I called httpclient code:
> 
> 
>       NTCredentials creds = new NTCredentials(context.getUserName(),
> context.getPassword(),
>         context.getServer(), context.getDomain());
>       HttpState httpState = new HttpState();
>       httpState.setAuthenticationPreemptive(true);
>       HttpClient client = new HttpClient();
> 
>       httpState.setCredentials(new AuthScope(context.getHost(),
> context.getPort(),
>         AuthScope.ANY_REALM, AuthScope.ANY_SCHEME), creds);
>       GetMethod get = new GetMethod(context.getSitePath());
> 
>       get.setDoAuthentication(true);
>       setCredentialsProvider(client, creds);
>       client.getParams().setAuthenticationPreemptive(true);
>       client.setState(httpState);
>       // execute method and handle any error responses.
>       client.executeMethod(get);
> 
> Thanks!
> Jeff


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to