我还没有这样做过AuthenticationSuccessEvent
,但会尝试做同样的事情LogoutFilter
。
不幸的 LogoutFilter
是,注销直接在其处理程序方法中处理LogoutFilter.doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
,因此直接调用它是一种黑客行为,(但并非不可能)
@Autowired
LogoutFilter logoutFilter;
private void doLogout() {
MockHttpServletRequest request = new MockHttpServletRequest(
"GET",
"http://myApp" + this.logoutFilter.getFilterProcessingUrl());
this.logoutFilter.doFilter(request, new MockHttpServletResponse(),
new MockFilterChain());
}
但这是一个黑客。-- Anway,我会从这个开始。它有效,并表明这个概念证明有效,然后我将实施一个更干净的解决方案:
LogoutHandler
获取所有注册到的 s的列表LogoutFilter
并直接调用它们然后触发logoutSuccessHandler.onLogoutSuccess
(这正是 LogoutFilter 所做的)。
@Autowired
List<LogoutHandler> logoutHandlers;
@Autwired
LogoutSuccessHandler logoutSuccessHandler;
private void doLogout() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
for (LogoutHandler handler : handlers)
handler.logout(request, response, auth);
logoutSuccessHandler.onLogoutSuccess(request, response, auth);
}
但
如果您只想因为某些限制而阻止用户登录,那么实现接口并使用orUserDetailsChecker
注册您的实现会更容易和更清晰 (很可能您使用which 是 的子类)AbstractUserDetailsAuthenticationProvider.preAuthenticationChecks
.postAuthenticationChecks
DaoAuthenticationProvider
AbstractUserDetailsAuthenticationProvider
(提示:(void UserDetailsChecker.check(UserDetails toCheck)
这是唯一的一种方法UserDetailsChecker
) - 如果要阻止用户登录,需要抛出异常。)
private class Demo implements UserDetailsChecker {
public void check(UserDetails user) {
if (!user.isAccountNonLocked())
throw new LockedException("User account is locked");
if (!user.isEnabled())
throw new DisabledException("User is disabled"));
if (!user.isAccountNonExpired())
throw new AccountExpiredException("User account has expired");
//And here comes you!
}
}