基于Spring Boot 2与Spring Security,通过Spring AOP获取调用方法的当前用户
通过Spring AOP获取Spring Security当前登录用户的实现思路
嘿,针对你用Spring Boot 2 + Spring Security结合AOP获取当前用户的需求,我给你梳理下具体实现思路,结合你已有的切面代码来调整:
1. 核心:通过Spring Security的SecurityContextHolder获取用户信息
Spring Security会把当前请求的登录用户信息存在SecurityContext中,而SecurityContextHolder是访问这个上下文的入口。你可以通过它拿到Authentication对象,进而提取用户的详细信息。
2. 修改你的切面代码,整合用户获取逻辑
首先先修正你原来的切面表达式(多了个右括号,会导致切面不生效),然后添加用户获取的逻辑:
@Aspect @Component public class LogAspect { // 修正execution表达式:匹配controller包下所有类的所有方法 @Before("execution(* com.moplogy.controller.*.*(..))") public void getAllAdvice(JoinPoint joinPoint) { // 获取当前登录用户 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String currentUser = "匿名用户"; // 过滤未登录/匿名用户的情况 if (authentication != null && authentication.isAuthenticated() && !(authentication instanceof AnonymousAuthenticationToken)) { Object principal = authentication.getPrincipal(); // 处理UserDetails类型的用户(Spring Security默认的用户对象) if (principal instanceof UserDetails) { currentUser = ((UserDetails) principal).getUsername(); } else { // 如果是自定义的用户对象,强转为对应类型即可 currentUser = principal.toString(); } } // 输出方法信息和用户信息 System.out.println("method called: " + joinPoint.getSignature().getName()); System.out.println("current user: " + currentUser); } }
3. 关键注意事项
- 表达式修正:原表达式
execution(* com.moplogy.controller.*))语法错误,正确写法是execution(* com.moplogy.controller.*.*(..)),其中*.*(..)表示匹配包下所有类的所有方法(任意参数)。 - 空指针防护:一定要判断
authentication是否为空,以及是否是AnonymousAuthenticationToken(未登录时Spring Security会生成这个对象),避免空指针异常。 - 自定义用户扩展:如果你实现了自定义的
UserDetails(比如CustomUser),可以直接强转获取更多字段:if (principal instanceof CustomUser) { CustomUser customUser = (CustomUser) principal; String username = customUser.getUsername(); Long userId = customUser.getUserId(); // 提取其他自定义字段 } - 线程安全:
SecurityContextHolder默认用ThreadLocal存储上下文,每个请求线程独立持有自己的安全上下文,无需担心多线程问题。
内容的提问来源于stack exchange,提问作者robert trudel
相关产品推荐
相关产品推荐

