我使用的是spring.security.version = 3.1.0.RELEASE。我遇到的问题是由于某种原因,不会触发AuthenticationFailureCredentialsExpiredEvent。
在调试代码时,我发现AbstractUserDetailsAuthenticationProvider确实在控制台中显示“用户帐户凭据已过期”。但我仍然感到困惑的是为什么没有触发关注的事件。
这是我的代码:
class JpaUserDetails implements UserDetails {
...
...
@Override
public boolean isCredentialsNonExpired() {
if (some logic) {
return true;
}
else {
return false;
}
}
}
我确实看到AbstractUserDetailsAuthenticationProvider在控制台“用户帐户凭据已过期”中显示以下几行代码:
public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitilizeBean, MessageSourceAware {
...
...
private class DefaultPostAuthenticationChecks implements UserDetailsChecker {
public void check(UserDetails user) {
if(!user.isCredentialsNonExpired()) {
logger.debug("User account credentials have expired");
throw new CredentialsExpiredException(message.getMessage(
"AbstractUserDetailsAuthenticationProvider.credentialsExpired",
"User credentials have expired"), user);
}
}
}
}
问题是,当用户凭据已过期时,我希望Spring生成我正在以下列方式处理的事件AuthenticationFailureCredentialsExpiredEvent:
class SecurityEventDispatcher implements ApplicationListener<ApplicationEvent> {
final List<SecurityEventListener> listeners = new ArrayList<SecurityEventListener>();
public void registerListener(SecurityEventListener listener) {
this.listener.add(listener);
}
public void onApplicationEvent(ApplicationEvent event) {
for (SecurityEventListener listener : this.listeners) {
if(listener.canHandle(event)) {
listener.handle(event);
}
}
}
}
这就是我处理登录失败事件的方式:
public class LoginFailedEvent extends SecurityEventListener {
@Override
public boolean canHandle(Object event) {
if(event instanceof AbstractAuthenticationFailureEvent) {
return true;
}
else {
return false;
}
}
@Override
public void handle(Object event) {
if (event instanceof AuthenticationFailureBadCredentialsEvent) {
// do something
}
if (event instanceof AuthenticationFailureCredentialsExpiredEvent) {
// do something
}
}
}
我之前提到的问题是从不触发AuthenticationFailureCredentialsExpiredEvent。我已经测试了AuthenticationFailureBadCredentialsEvent,它可以正常工作。
这是因为凭据不良而得到的结果:(工作正常)
org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent
这是我在密码过期时遇到的情况:
带有failureCause = null的ServletRequestHandledEvent:url = [/ app / loginFailure]
有谁知道可能出现什么问题?任何帮助将受到高度赞赏。
答案 0 :(得分:1)
以下是这个问题的答案,因为关于这个问题的文献不多。
您可能需要设置ProviderManager ('s)eventPublisher不是 NullEventPublisher。没有一种简单的方法可以通过 标签,所以你会想要创建 AuthenticationProvider使用标准bean配置和注入 它成为ProviderManager的标准Spring Bean。
Rob Winch - 春季安全负责人
答案 1 :(得分:0)
如果有人遇到此问题,只需将弹簧安全性升级到3.1.2或+,问题就解决了。