Spring AOP Spring 安全

Spring AOP Spring Security

我试图在用户单击注销按钮时将日志保存到数据库中。 对于登录,我使用 @Before... 方法,AOP 正在执行此方法并将记录保存到数据库中。

但是注销有点不同,因为我没有特定的注销方法,而是由 Spring 安全处理:

   // ...
   .and()
   .logout()
   .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
   .logoutSuccessUrl("/")
   // ...

在注销发生之前执行方法的最佳做法是什么?

谢谢, R.

最后,我使用实现 LogoutSuccessHandler 接口的 CustomLogoutSuccessHandler 找到了解决此问题的方法,但我无法使用 AOP,因为当调用该方法时,安全处理程序无法再访问用户信息,因为已断开连接。 但是接口方法 onLogoutSuccess 附带了 Authentication 参数,我可以用它来检索用户信息并将其存储到数据库中,然后再关闭 http 会话。

如有其他解决方案请回复

谢谢 R.

你的方法很好,我已经明确地将 spring 安全注销成功 url 映射到 spring 控制器,如下例所示:

@RequestMapping(value="/logout", method = RequestMethod.GET)
public String logoutPage (HttpServletRequest request, HttpServletResponse response) {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth != null){    
        new SecurityContextLogoutHandler().logout(request, response, auth);
    }
    return "redirect:/login?logout";//You can redirect wherever you want, but generally it's a good practice to show login screen again.
}
<logout
 logout-success-url="/logout"
 delete-cookies="JSESSIONID" />

在控制器方法中你做你的审计工作。

使用spring aop,你可以这样做:

@Before("execution(* org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler.logout(..))")
public void beforeLogout(JoinPoint joinPoint) throws Throwable {        
    System.out.println(
                ">>> Aspect : User " + SecurityContextHolder.getContext().getAuthentication().getName() + " successfully logged out.");
}