Spring Boot获取当前登录用户返回空值问题求助
我在使用Spring Boot 2.5.6版本时,尝试获取当前登录用户信息来创建用户档案,用了以下代码查询用户,但日志里返回的user是空值。网上查的都说这是获取当前登录用户的正确方式:
Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (!(authentication instanceof AnonymousAuthenticationToken)){ currentUserName = authentication.getName(); user = userRepository.findByTag(currentUserName); log.info("User is logged in "+ user); }
排查步骤:
先核对
currentUserName与数据库tag字段值是否匹配
加一行日志输出当前获取到的用户名:log.info("当前登录用户名: " + currentUserName);拿着这个值去数据库里手动查询,看有没有对应的用户记录。如果用户名和
tag字段不匹配,查询自然返回null。检查SecurityContext的跨线程传递问题
Spring Security默认用ThreadLocal存储上下文,如果你的代码是异步执行(比如用了@Async),线程切换后ThreadLocal里的上下文会丢失,导致获取到的authentication不是当前登录用户的。这种情况可以修改SecurityContextHolder的存储策略:SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);或者配置异步任务执行器时传递上下文。
确认Authentication对象的有效性
打印完整的Authentication对象,看里面的用户信息是否正常:log.info("Authentication详情: " + authentication);检查principal、authorities等字段,确认是不是实际登录的用户信息,而不是空的或匿名对象。
检查
userRepository.findByTag()的实现逻辑
确认这个方法的SQL/JPQL语句是否正确,比如字段名是不是tag(有没有写成username之类的),可以直接在数据库执行SELECT * FROM user WHERE tag = '你的currentUserName',验证是否有结果。核对Spring Security配置
确保自定义的UserDetailsService返回的UserDetails对象中,getUsername()方法返回的就是用户的tag字段值。如果这里返回的是用户名而非tag,那authentication.getName()拿到的就不是你要查的tag值。
内容的提问来源于stack exchange,提问作者Paul Nyishar

