【问题标题】:How to show error message when user does not exist using Spring Security?当使用 Spring Security 的用户不存在时如何显示错误消息?
【发布时间】:2013-06-04 20:44:33
【问题描述】:

我是 Spring Security 的新手。我尝试使用条件is:question [spring-security] error message when user does not exist 进行搜索,但没有任何帖子帮助。

目前我使用Spring Security 3.1 在我的网络应用程序中验证用户。我的实现如下:

  1. DaoAuthenticationProvider 用作AuthenticationProvider
  2. UserDetailsService 编写一个实现,供DaoAuthenticationProvider 使用

这里是userDetailsServiceImpl豆:

@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;
    }

}

我在login.ftl(我正在使用freemarker)中显示错误消息如下:

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

一切正常,除了输入不存在的用户名时登录页面上没有显示任何消息。我检查了console,但没有发现任何异常。

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)

在这种情况下是否可以显示错误消息?

【问题讨论】:

  • userDao.getUserByUsername 是否在某处抛出 UsernameNotFoundException?在我看来,除非您的 DAO 在某处抛出 UsernameNotFoundException ,否则用户将始终通过身份验证,因为您正在创建一个启用的新 Spring Security 用户,无论您的 DAO 返回的现有用户如何
  • UsernameNotFoundException 没有被抛出,也没有另一个 exception 被抛出(我确实仔细观察了控制台)。谢谢!

标签: java spring authentication spring-security


【解决方案1】:

由于您正在实现 UserDetailsS​​ervice,因此您需要手动抛出 UsernameNotFoundException,以便告诉 Spring Security 未找到尝试登录的用户。应该是这样的:

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");
}

【讨论】:

  • 谢谢!它起作用了,但我不明白 为什么existingUser.getUsername() 在我的代码中没有抛出NullPointerException 虽然existingUsernull??
  • 好问题。取决于调用 getUserByUsername 时您的 DAO 返回的内容。不是返回一个空对象吗?
  • 我调试发现existingUser 现在是null。如果不是null,您的代码将类似于我的代码:D
  • @ControllerAdvice ExceptionController 无法监听 UsernameNotFoundException
猜你喜欢
  • 2014-01-01
  • 2011-09-02
  • 2017-10-10
  • 2011-04-20
  • 2021-06-06
  • 2011-07-23
  • 2018-10-30
  • 2011-12-31
相关资源
最近更新 更多