hc-httpclient-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Oleg Kalnichevski <ol...@apache.org>
Subject Re: Potential account lockouts when using authentication using concurrent http requests
Date Tue, 16 Sep 2008 17:44:18 GMT
On Mon, 2008-09-15 at 12:53 -0700, Henrich Kraemer wrote:
> Lets consider an application which uses credentials similar to a web
> browser:
> 1. Credentials previously accepted by a server are automatically reused for
> the same authentication scope.
> 2. If a user gets prompted for credentials they are only remembered after
> the server accepts them. The user can indicates to persist them beyond the
> current session.
> 3. Credentials which are not accepted by the server are invalidated and no
> longer reused. They are removed from session state and/or  the persisted
> credential store.
> The application uses
> - HttpClient 3.
> - Multiple threads to execute HttpClient requests. All threads use a single
> (global) HttpClient instance with a MultiThreadedHttpConnectionManager.
> - a CredentialProvider to provide credentials.
> Consider a server which locks out users after receiving a bad password for
> a particular user more than 3 consecutive times.
> Now if the application uses 4 or more threads to access this server a user
> can get locked out:
> Scenario 1)  when the password has changed but HttpClient.state or the
> CredentialProvider use old credentials. All threads send the old
> credentials before noticing that they are no longer valid. I believe this
> can happen even if the CredentialProvider provided them only once as other
> threads will use the state of HttpState (I am looking at HttpClient 3.0
> code, but I believe this hasn't changed, looking at release notes)
> (see org.apache.commons.httpclient.HttpMethodDirector.promptForCredentials
> (AuthScheme, HttpParams, AuthScope))
> Scenario 2) The user provides bad credentials but a correct username. The
> provided credentials are stored in the HttpState associated with the
> HttpClient instance. The other threads send the bad credentials as well
> again picking them up via the HttpClient.state field. This would require a
> good amount of bad luck, but I believe it might happen.
> I would think a solution would involve that concurrent requests requiring
> the credentials for the same authentication scope would have to wait for
> the server response before sending these credentials again (or refraining
> from that and instead prompting again). This could be implemented by the
> CredentialProvider. However the HttpState used in HttpClient 3 seems to
> prevent this be without issues. On the other hand it might be useful for
> many apps so perhaps it should be implemented by the framework and apps
> responsibility would be limited to prompt users and store credentials.

Hi Henrich,

This is an inherent design issue. When requests are executed
concurrently from multiple threads there is always a chance that enough
requests get submitted in order to get the account locked before the
application stands a change to react to the first authentication
failure. The only way around this problem is serializing / synchronizing
execution of requests. If you can live with occasional account lockouts,
then you can execute a single request in order to validate the
credentials and then proceed with executing more requests concurrently
from multiple threads. 

> Is there a way for an application as sketched out to let HttpClient 3
> handle the authentication but avoid the lock out problem?
> How would this be done using HttpClient 4?
> An issue for an application which would implement this is to determine
> whether provided credentials have been accepted by the server or not. In
> HttpClient 3 one can assume that if the CredentialProvider is called that
> any previously provided credentials were wrong. However the app can only
> notice that it was accepted by waiting for HttpClient.executeMethod() to
> return. However one would want to know as soon as possible to increase
> concurrency. It seems that one would have to switch off redirection
> handling.

Unfortunately CredentialProvider stuff in HttpClient 3.x is
fundamentally flawed. The idea of requesting new credentials in case of
an authentication failure from inside the main execution loop was

> Has HttpClient 4 mechanism by which an application can determine as soon as
> possible whether credentials used were accepted or rejected?

When using HttpClient 4.0 one is advised to do the following:

* populate the credentials store with the default credentials if
* execute the request
* if the request fails with status code 401 or 407, prompt the user for
new credentials
* update the credentials store according to the user input
* retry

One can also use the same logic with HttpClient 3.x.

Hope this helps


> Thanks,
> Henrich

To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org

View raw message