Tuna
Tuna

Reputation: 3005

How to show error message when user does not exist using Spring Security?

I'm new to Spring Security. I tried to search with criteria is:question [spring-security] error message when user does not exist but no post helps.

Currently I use Spring Security 3.1 to authenticate user in my web application. My implementation as below:

  1. use DaoAuthenticationProvider as AuthenticationProvider
  2. write an implementation for UserDetailsService which is used by DaoAuthenticationProvider

Here is userDetailsServiceImpl bean:

@Service("userDetailsServiceImpl")
@Transactional(readOnly = true, propagation = Propagation.REQUIRED)
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User existingUser = this.userDao.getUserByUsername(username);
        // TODO create a schema for storing ROLEs in database
        List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
        roles.add(Role.USER);

        org.springframework.security.core.userdetails.User user = new org.springframework.security.core.userdetails.User(
                existingUser.getUsername(), existingUser.getPassword(), existingUser.getEnable(), true, true, true, roles);
        return user;
    }

}

I show error message in login.ftl(I'm using freemarker) as below:

<#if Session.SPRING_SECURITY_LAST_EXCEPTION?? 
    && Session.SPRING_SECURITY_LAST_EXCEPTION.message?has_content>
    <br />Message: ${Session.SPRING_SECURITY_LAST_EXCEPTION.message} 
</#if>

Everything worked fine, except no message is shown up on login page when non existing username is entered. I checked console but didn't see anything out of the ordinary.

2013-06-09 02:25:38.082 [DEBUG] [org.springframework.orm.hibernate4.HibernateTransactionManager] - Creating new transaction with name [net.dntuan.training.mvc.security.authentication.UserDetailsServiceImpl.loadUserByUsername]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; '' (AbstractPlatformTransactionManager.java:366)
2013-06-09 02:25:38.162 [DEBUG] [org.springframework.orm.hibernate4.HibernateTransactionManager] - Opened new Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction (HibernateTransactionManager.java:416)
2013-06-09 02:25:38.167 [DEBUG] [org.springframework.orm.hibernate4.HibernateTransactionManager] - Preparing JDBC Connection of Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] (HibernateTransactionManager.java:426)
2013-06-09 02:25:38.234 [DEBUG] [org.springframework.orm.hibernate4.HibernateTransactionManager] - Exposing Hibernate transaction as JDBC transaction [org.postgresql.jdbc4.Jdbc4Connection@2b9fd66a] (HibernateTransactionManager.java:487)
Hibernate: select this_.id as id1_1_0_, this_.enable as enable2_1_0_, this_.fullname as fullname3_1_0_, this_.password as password4_1_0_, this_.username as username5_1_0_ from public.user this_ where this_.username=?
2013-06-09 02:25:38.367 [TRACE] [org.springframework.orm.hibernate4.HibernateTransactionManager] - Triggering beforeCompletion synchronization (AbstractPlatformTransactionManager.java:936)
2013-06-09 02:25:38.367 [DEBUG] [org.springframework.orm.hibernate4.HibernateTransactionManager] - Initiating transaction rollback (AbstractPlatformTransactionManager.java:844)
2013-06-09 02:25:38.367 [DEBUG] [org.springframework.orm.hibernate4.HibernateTransactionManager] - Rolling back Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] (HibernateTransactionManager.java:570)
2013-06-09 02:25:38.371 [TRACE] [org.springframework.orm.hibernate4.HibernateTransactionManager] - Triggering afterCompletion synchronization (AbstractPlatformTransactionManager.java:965)
2013-06-09 02:25:38.372 [DEBUG] [org.springframework.orm.hibernate4.HibernateTransactionManager] - Closing Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] after transaction (HibernateTransactionManager.java:632)

Is it possible to show an error message in this case?

Upvotes: 2

Views: 9962

Answers (1)

vincentks
vincentks

Reputation: 694

Since you are implementing UserDetailsService, you will need to throw UsernameNotFoundException manually, in order to tell Spring Security the user trying to login was not found. It would be something like this:

User existingUser = this.userDao.getUserByUsername(username);
if (existingUser != null) {
    List<GrantedAuthority> roles = new ArrayList<GrantedAuthority>();
    roles.add(Role.USER);

    org.springframework.security.core.userdetails.User user = new org.springframework.security.core.userdetails.User(
            existingUser.getUsername(), existingUser.getPassword(), existingUser.getEnable(), true, true, true, roles);
    return user;
} else {
    throw new UsernameNotFoundException("User not found");
}

Upvotes: 6

Related Questions