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. 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. Has HttpClient 4 mechanism by which an application can determine as soon as possible whether credentials used were accepted or rejected? Thanks, Henrich
