Aug 26th, 2004, 05:03 PM
BadCredentialsException too restrictive?
Our client wants to display on the login form whether the authentication failed due to unknown username or invalid password. I've looked at DaoAuthenticationProvider and discovered that in the getUserFromBackend private method, the code catches any UsernameNotFoundException thrown by the AuthenticationDao, and throws in its place a BadCredentialsException.
Could we develop a means for the client layer to tell the difference between failures due to invalid username or invalid password. We've thrown around some ideas here:
* Add a BadPrincipalException to match the BadCredentialsException
* Add a flag to BadCredentialsException indicating username or password
* Stop catching the UsernameNotFoundException - it is a subclass of AuthenticationException
* Wrap the UsernameNotFoundException inside the BadCredentialsException
We also experimented with using the listener for the events, but didn't find a clean way to communicate the event to a jsp.
Aug 26th, 2004, 05:12 PM
Are you sure you want to do this? Most security systems you encounter will reject with a non-specific error, so people don't target in on an account and then find its password. eg:
$ ssh firstname.lastname@example.org
Permission denied, please try again.
(I'm only guessing there's not a fdcldvlkjfdvlkjfdvlkj user!)
Aug 26th, 2004, 05:20 PM
I agree and I've explained this to my client. They still want it.
We had a workaround idea. Subclass the filter that catches the BadCredentialsException and use our ProfileService to attempt to lookup the user. If the service can't find it, we know the username is bad. Not elegant but it works.
Aug 26th, 2004, 06:17 PM
Upon reflection I think your client position is reasonable:
- Most web applications are public-facing and you want to make it as easy as possible for people to know what the problem is.
- Most web applications offer a "forgotten password" use case which is another way of determining valid login names anyway.
Given this, I've added to DaoAuthenticationProvider in CVS HEAD a new property, hideUserNotFoundExceptions. It defaults to true, giving the current more secure behaviour. You can set it to false and it will result in UsernameNotFoundException being thrown instead.