2

对于 Spring Security,我需要在AuthenticationSuccessEvent. 如果用户使用有效凭据登录,我想根据一些限制注销用户。

我怎样才能做到这一点?

@Override
public void onApplicationEvent(AbstractAuthenticationEvent appEvent) {
    if (appEvent instanceof AuthenticationSuccessEvent) {
        if(Condition true)
        {
            //LOGOUT
        }
    }
4

1 回答 1

1

我还没有这样做过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.postAuthenticationChecksDaoAuthenticationProviderAbstractUserDetailsAuthenticationProvider

(提示:(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!
    }
}
于 2013-09-17T07:02:23.193 回答