Spring Security 在登录失败时返回 String 作为主体而不是 UserDetails?
Posted
技术标签:
【中文标题】Spring Security 在登录失败时返回 String 作为主体而不是 UserDetails?【英文标题】:Spring security returns String as principal instead of UserDetails on failed login? 【发布时间】:2013-07-01 10:48:48 【问题描述】:要么我遗漏了一些东西,要么这就是它的工作原理......
即,我实现了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
实例,对于这种情况。
想法?
【问题讨论】:
【参考方案1】:由于我们正在处理身份验证失败,因此事件中的 Authentication
对象是提交给 AuthenticationManager
的对象(并且被拒绝)。
在典型情况下,这将是 UsernamePasswordAuthenticationToken
,其中“主要”属性是提交的用户名。
AuthenticationManager
支持许多不同的身份验证机制,从它的角度来看,不能保证UserDetailsService
甚至参与身份验证。它只知道身份验证令牌未被接受(出现异常)并相应地发布事件。
替代选项是自定义正在使用的AuthenticationProvider
或插入AuthenticationFailureHandler
(例如,如果您使用表单登录)并在那里完成额外的工作。
【讨论】:
所以,这实际上是它应该的方式......?我已经在使用AuthenticationSuccessHandler
进行计数器重置,不知道这是否是正确的方法,我没有想到尝试使用AuthenticationFailureHandler
。
是的,应该是这样的。该事件表示“这是失败的身份验证请求”,并且身份验证请求仅包含用户的字符串标识符。以上是关于Spring Security 在登录失败时返回 String 作为主体而不是 UserDetails?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot + Spring Security Restful 登录