【问题标题】:Logout user in custom event listener在自定义事件侦听器中注销用户
【发布时间】:2013-09-21 09:55:33
【问题描述】:

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

我该怎么做?

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

【问题讨论】:

  • 您能详细说明您的用例吗?简而言之,您不能在 ApplicationListener 中执行此操作。
  • 如果用户尝试使用错误的凭据登录 3 次,我想阻止他五分钟。因此,在 3 次错误尝试后,即使用户使用正确的凭据登录,它也应该被注销。
  • stackoverflow.com/questions/5351391/… 这有几个解决方案。基本上你想防止这种情况,在 x 次登录失败后根本不允许成功登录。
  • 但我想阻止用户登录仅五分钟。
  • 对于阻塞我有计数 10。我正在更新我的数据库和最后一次登录。所以如果计数是 3 并且时间少于 5 分钟,我希望它在成功登录后注销。跨度>

标签: java spring spring-security


【解决方案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());
}

但这是一个 hack。 -- Anway,我会从这个开始。它有效,并表明这个概念证明有效,然后我将实施一个更干净的解决方案:

获取向LogoutFilter 注册的所有LogoutHandlers 的列表并直接调用它们,然后触发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);
}

但是

如果您只是因为某些限制而想阻止用户登录,那么实现接口UserDetailsChecker 并使用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!
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    相关资源
    最近更新 更多