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

Spring Security AuthenticationManager出现StackOverflowError问题求助

解决Spring Security JWT认证中的StackOverflowError问题

问题分析

你遇到的StackOverflowError主要由以下配置和代码逻辑问题导致:

  1. SecurityConfig配置冲突:继承SecurityConfigurerAdapter的同时手动定义SecurityFilterChain,引发Spring Security内部配置循环依赖。
  2. AuthenticationManager关联缺失:未在Security上下文绑定UserDetailsService,导致认证流程出现循环调用。
  3. 冗余数据库查询:登录方法中重复查询数据库,虽不直接引发栈溢出,但不符合规范且可能隐含其他问题。

修正方案

1. 重构SecurityConfig配置

移除不必要的SecurityConfigurerAdapter继承,明确关联UserDetailsService:

@Configuration
@EnableMethodSecurity(securedEnabled = true)
public class SecurityConfig {

    private final UserDetailsService userDetailsService;

    // 注入你的UserDetailsService实现类(UserAppService)
    public SecurityConfig(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(AbstractHttpConfigurer::disable)
            .cors(Customizer.withDefaults())
            .authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
            .httpBasic(Customizer.withDefaults())
            // 绑定UserDetailsService到Security上下文
            .userDetailsService(userDetailsService);

        return http.build();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
        return authConfig.getAuthenticationManager();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

2. 优化登录控制器逻辑

从认证后的Authentication对象直接获取UserDetails,避免冗余查询,并遵循JWT标准格式添加Bearer前缀:

@RestController
@RequestMapping("log/auth")
public class LogUserController {
    private final AuthenticationManager authenticationManager;
    private final JwtUtil jwtUtil;

    // 移除不必要的UserAppRepository注入
    public LogUserController(AuthenticationManager authenticationManager, JwtUtil jwtUtil) {
        this.authenticationManager = authenticationManager;
        this.jwtUtil = jwtUtil;
    }

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginDto loginDto) {
        UsernamePasswordAuthenticationToken authToken = 
            new UsernamePasswordAuthenticationToken(loginDto.getEmail(), loginDto.getPassword());
        
        // 执行认证,成功后Authentication对象包含已验证的UserDetails
        Authentication authentication = authenticationManager.authenticate(authToken);
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();

        String jwt = jwtUtil.create(userDetails.getUsername());

        // 标准JWT响应头格式:Bearer + Token
        return ResponseEntity.ok()
            .header(HttpHeaders.AUTHORIZATION, "Bearer " + jwt)
            .build();
    }
}

3. 确保UserDetailsService实现正确

你的UserAppService需正确实现UserDetailsService,并使用PasswordEncoder处理密码验证:

@Service
public class UserAppService implements UserDetailsService {

    private final UserAppRepository userAppRepository;
    private final PasswordEncoder passwordEncoder;

    public UserAppService(UserAppRepository userAppRepository, PasswordEncoder passwordEncoder) {
        this.userAppRepository = userAppRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        UserApp user = userAppRepository.findByEmail(email)
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + email));
        
        // 返回Spring Security的User对象,包含权限信息
        return User.builder()
                .username(user.getEmail())
                .password(user.getPassword()) // 确保数据库中存储的是BCrypt加密后的密码
                .roles(user.getRoles().toArray(new String[0])) // 根据你的角色结构调整
                .build();
    }
}

关键注意事项

  • 确保数据库中用户密码是通过BCryptPasswordEncoder加密后的字符串,否则认证会失败。
  • 移除SecurityConfig对SecurityConfigurerAdapter的继承,避免与SecurityFilterChain配置冲突,这是解决StackOverflowError的核心。

内容的提问来源于stack exchange,提问作者Carlos Daniel Lasso Gómez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 17:13:12