问题描述
要么我失去了一些东西,或者这是如何工作的?结果
也就是说,我实现了的UserDetailsService
和子类( APPUSER
以下)春的实用程序类用户
,(实现的UserDetails
)。如果它的事项,它是这样的:
Either I'm missing something, or this is how it works...
Namely, I implemented UserDetailsService
, and sub-classed (AppUser
below) spring utility class User
, (that implements UserDetails
). If it matters, it goes something like this:
@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;
}
然后我试图使用这种方法来实现帐户锁定:
Then I tried to implement account locking using this approach:
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
,同时试图从提供的事件参数的主要对象(主要目的是类型的字符串
)。我的意思是,OK - 我可以载入我的 SystemUser
按用户名再次,要解决这个问题,但我没想到这个结果...
我认为,即使源文档指出 getPrincipal()
应该返回的UserDetails
例如,对于此方案。结果
思考?
However, I ran into java.lang.ClassCastException
while trying to get the principal object from the supplied event argument (principal object was of type String
). I mean, OK - I can just load my SystemUser
by username again, to solve the problem, but I did not expect this...
I think that even the source documentation states that getPrincipal()
should return UserDetails
instance, for this scenario.
Thoughts?
推荐答案
由于我们正在处理一个身份验证失败,在事件的验证
对象是这是一提交给的AuthenticationManager
(和被拒绝)。
Since we are dealing with an authentication failure, the Authentication
object in the event is the one which was submitted to the AuthenticationManager
(and which was rejected).
在通常情况下,这将是一个 UsernamePasswordAuthenticationToken
里的校长属性提交的用户名。
In a typical scenario this would be a UsernamePasswordAuthenticationToken
where the "principal" property is the submitted username.
的的AuthenticationManager
支持许多不同的认证机制,并从它的角度来看,有没有保证一个的UserDetailsService
是即使参与认证。它只知道该身份验证令牌不被接受(有一个例外),并据此发布了此次活动。
The AuthenticationManager
supports lots of different authentication mechanisms and, from its perspective, there's no guarantee that a UserDetailsService
is even involved in the authentication. All it knows is that the authentication token was not accepted (there was an exception) and it publishes the event accordingly.
替代选项自定义使用的AuthenticationProvider
或插在 AuthenticationFailureHandler
(如果你使用的形式-Login,例如)和做额外的工作在那里。
Alternative options are to customize the AuthenticationProvider
in use or plug in an AuthenticationFailureHandler
(if you're using form-login, for example) and do the extra work in there.
这篇关于春季安全返回的字符串作为本金,而不是在登录失败的UserDetails?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!