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

Les*_*ess 9 java authentication spring login spring-security

要么我错过了一些东西,要么就是它的工作原理......
也就是说,我实现了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;
}
Run Code Online (Sandbox Code Playgroud)

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

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 ?
    // ...
}
}
Run Code Online (Sandbox Code Playgroud)

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

Sha*_*eep 5

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

在典型情况下,这将是UsernamePasswordAuthenticationToken"principal"属性是提交的用户名.

AuthenticationManager支持许多不同的认证机制,并从它的角度来看,有没有保证,一个UserDetailsService是连参与认证.它只知道身份验证令牌未被接受(存在异常)并且相应地发布事件.

替代选项是自定义AuthenticationProvider正在使用或插入AuthenticationFailureHandler(例如,如果您使用表单登录)并在那里做额外的工作.