Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security: Custom exception message from UserDetailsService

I am able to display the SPRING_SECURITY_LAST_EXCEPTION.message ("Bad Credentials") when a user tries to log in with incorrect credentials or user is disabled for some reason.

I want to display a custom message for the case where the user is disabled, not show "Bad Credentials" instead say "You have been disabled...blah,blah...". How do I do that?

I am using UserDetailsService for providing username/password in spring security.

like image 970
Jayz Avatar asked Jul 03 '13 04:07

Jayz


People also ask

What is UserDetailsService in Spring Security?

UserDetailsService is used by DaoAuthenticationProvider for retrieving a username, password, and other attributes for authenticating with a username and password. Spring Security provides in-memory and JDBC implementations of UserDetailsService .

How to handle Exception in Spring security?

Spring security exceptions can be directly handled by adding custom filters and constructing the response body. To handle these exceptions at a global level via @ExceptionHandler and @ControllerAdvice, we need a custom implementation of AuthenticationEntryPoint.

What is the purpose of the UserDetailsService?

The UserDetailsService interface is used to retrieve user-related data. It has one method named loadUserByUsername() which can be overridden to customize the process of finding the user. It is used by the DaoAuthenticationProvider to load details about the user during authentication.


1 Answers

You need to set hideUserNotFoundExceptions property of AbstractUserDetailsAuthenticationProvider to false. (This means this solution is dependent on the Spring Security code which might change in the future).

Here are the steps:

(1) Define a DaoAuthenticationProvider bean (if you already have one then set its hideUserNotFoundExceptions property to false). Here is Java config style:

    @Bean
public AuthenticationProvider daoAuthenticationProvider() {
    DaoAuthenticationProvider impl = new DaoAuthenticationProvider();
    impl.setUserDetailsService(yourUserDetailsService());
    impl.setHideUserNotFoundExceptions(false) ;
    return impl ;
}

(2) Configure authentication manager with above provider:

<authentication-manager alias="authenticationManager">
    <authentication-provider ref="daoAuthenticationProvider"/>
<!-- other providers if any -->
</authentication-manager>

(3) Create an exception extending the UsernameNotFoundException:

    public class DisabledException extends UsernameNotFoundException {

    public DisabledException(String msg) {
    super(msg);
    }

    /* other constructors */    
}

(4) In your UserDetailsService, throw the above exception with any message key you like:

    throw new DisabledException(messages.getMessage(
                        "AbstractUserDetailsAuthenticationProvider.disabled", "User is disabled"));

Here messages is SpringSecurityMessageSource.getAccessor()

like image 184
Ritesh Avatar answered Nov 16 '22 00:11

Ritesh