简体   繁体   English

在自定义事件侦听器中注销用户

[英]Logout user in custom event listener

For Spring Security, I am required to log out a user in AuthenticationSuccessEvent . 对于Spring Security,我需要在AuthenticationSuccessEvent注销用户。 If the user logs in with valid credentials, I want to log out the user based on some constraints. 如果用户使用有效的凭据登录,我想根据一些限制注销该用户。

How can I do this? 我怎样才能做到这一点?

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

I haven't done this in a AuthenticationSuccessEvent yet, but what would try is to do the same thing the LogoutFilter does. 我尚未在AuthenticationSuccessEvent完成此操作,但是尝试做的是LogoutFilter所做的相同操作。

Unfortunaly the LogoutFilter does the logout handling directly in its handler method LogoutFilter.doFilter(ServletRequest req, ServletResponse res, FilterChain chain) , so it would be a hack to invoke it diretly, (but not impossible) 不幸的是, 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());
}

But this is a hack. 但这是一个hack。 -- Anway, I would start with this. -嗯,我将从这个开始。 It it works, and show that this prove of concept works, then I would implment a more clean solution: 它确实有效,并表明此概念证明有效,然后我将采用一种更为简洁的解决方案:

Obain a list of all LogoutHandler s that are registered with the LogoutFilter and invoke them directly and then fire logoutSuccessHandler.onLogoutSuccess (that is exactly what the LogoutFilter does). Obain所有的列表LogoutHandler与该注册小号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);
}

BUT

if you only want to prevent the user from login because of some constraints, it would be much easyer and cleaner to implement the interface UserDetailsChecker and register you implementation with AbstractUserDetailsAuthenticationProvider.preAuthenticationChecks or .postAuthenticationChecks (It is likely that you use DaoAuthenticationProvider which is a subclass of AbstractUserDetailsAuthenticationProvider ) 如果仅由于某些限制而只希望阻止用户登录,则实现接口UserDetailsChecker并向AbstractUserDetailsAuthenticationProvider.preAuthenticationChecks.postAuthenticationChecks注册实现的实现会更加容易和.postAuthenticationChecks (很可能您使用的是DaoAuthenticationProvider ,它是一个子类的AbstractUserDetailsAuthenticationProvider

(Hint: void UserDetailsChecker.check(UserDetails toCheck) (that is the only one method of UserDetailsChecker ) - need to throw a Exception if it want to prevent the user from logging in.) (提示: 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!
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM