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

Spring Security返回null Authentication对象是什么原因?

问题原因及解决方法

1. 核心错误:安全配置路径放行规则冲突

你当前的安全配置中antMatchers("/auth/login", "/validate", "/**").permitAll()的/**规则匹配了所有请求路径,直接导致后续的anyRequest().authenticated()规则完全失效,所有请求都不会触发认证逻辑,SecurityContext上下文自然不会存储用户认证信息,所以获取到的Authentication为null。
修改方案:删除permitAll规则中的/**,仅放行无需认证的公开接口,修改后的配置片段如下:

@Override
protected void configure(HttpSecurity http) throws Exception {
  http.cors().and().csrf().disable()
  .authorizeRequests()
  // 仅放行公开接口,删除原来的/**规则,静态资源按需放行
  .antMatchers("/auth/login", "/validate", "/customer-photos/**").permitAll()
  .antMatchers("/admin/**").hasAuthority("ADMIN")
  .anyRequest().authenticated()
  // 其余原有配置保持不变
  .and()
  .exceptionHandling()
  .authenticationEntryPoint(jwtAuthenticationEntryPoint)
  .and()
  .formLogin().permitAll()
  .and()
  .sessionManagement()
  .maximumSessions(1)
  .and()
  .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
  .and()
  .logout().logoutUrl("/logout").logoutSuccessUrl("/auth/login")
  .deleteCookies("JSESSIONID");
  http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

2. 可选优化:直接从认证信息中取用户,避免重复查库

你在控制器中通过用户名二次查询用户的逻辑可以优化,因为Authentication的getPrincipal()方法返回的就是你在JWT过滤器中存入的MyUserDetails对象,直接转换即可,修改后的控制器代码如下:

@GetMapping(value="marketers/customers")
public List<Customer> getLlistByMarketerName()
{
  Authentication authentication = SecurityContextHolder.getContext().getAuthentication();  
  // 直接获取已存入的用户详情
  MyUserDetails userDetails = (MyUserDetails) authentication.getPrincipal();
  // 如果需要完整的User实体再按ID查询,比按用户名查询性能更高、更稳妥
  User loggedInUser = userRepo.findById(userDetails.getId()).orElseThrow(() -> new RuntimeException("用户不存在"));
  System.out.println("logged in user:"+ loggedInUser);
  return customerRepo.findByMarketer(loggedInUser);
}

3. 辅助排查点

如果修改配置后仍有问题,可以按以下顺序排查:

  • 检查请求是否正确携带Authorization请求头,格式是否为Bearer {token},注意Bearer和token之间的空格不能少
  • 检查UserAccountRepository中的findByUserName方法是否正确映射了User实体的userName字段,避免方法名拼写错误(比如误写为findByUsername,字段名首字母小写不匹配)
  • 在JWT过滤器的doFilterInternal方法中添加打印,确认是否成功解析到token中的用户名,是否成功执行了SecurityContextHolder.getContext().setAuthentication()逻辑

内容的提问来源于stack exchange,提问作者wizdemonizer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:24:06