You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:43:19