Spring安全性在登录失败时返回String作为主体,而不是UserDetails



要么我遗漏了什么,要么就是这样
也就是说,我实现了UserDetailsService,并将(下面的AppUser)spring实用程序类User(实现UserDetails)细分。如果重要的话,它是这样的:

@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
    // try loading user by its name
    SystemUser user = null;
    try {
        user = this.sysUserService.getByUsername(username);
        if(user == null)
            throw new UsernameNotFoundException("User not found!");
    }
    catch(Exception e) {
        throw new DataRetrievalFailureException(
                "Could not load user with username: " + username);
    }
    // load user rights, and create UserDetails instance
    UserDetails res = new AppUser(user, getUserAuthorities(user));
    return res;
}

然后我尝试使用以下方法实现帐户锁定:

public class LoginFailureEventListenter implements
ApplicationListener<AuthenticationFailureBadCredentialsEvent> {
// rest omitted for brevity
@Override
public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) {
    // ...
    SystemUser user = ((AppUser)event.getAuthentication().getPrincipal()).getSystemUser();
    // cast exception - how is it possible to obtain String 
    // instead of UserDetails object here ?
    // ...
}
}

但是,我在尝试从提供的事件参数中获取主体对象时遇到了java.lang.ClassCastException(主体对象的类型为String)。我的意思是,好吧,我可以再次用用户名加载我的SystemUser,以解决问题,但我没想到会这样
我认为,对于这种情况,即使是源文档也指出getPrincipal()应该返回UserDetails实例
想法?

由于我们正在处理身份验证失败,因此事件中的Authentication对象是提交给AuthenticationManager(但被拒绝)的对象。

在一个典型的场景中,这将是一个UsernamePasswordAuthenticationToken,其中"主体"属性是提交的用户名。

AuthenticationManager支持许多不同的身份验证机制,从它的角度来看,甚至不能保证UserDetailsService参与身份验证。它只知道身份验证令牌未被接受(出现异常),并相应地发布事件。

其他选项是自定义正在使用的AuthenticationProvider或插入AuthenticationFailureHandler(例如,如果您使用表单登录),并在其中执行额外的工作。

最新更新