Spring Security对接PostgreSQL读取登录用户出现StackOverflowError
问题根因
StackOverflowError是安全配置类出现循环调用导致的死循环:
- 你在
SecurityConfig中既自动注入了UserDetailsService实例,又重写了userDetailsService()方法并将其注册为Bean,而父类WebSecurityConfigurerAdapter的userDetailsService()方法本身会去容器中查找UserDetailsService类型的Bean,形成「找Bean→调用方法→找Bean」的无限循环,最终触发栈溢出。 - 除此之外还有一个隐藏问题:你的用户实体类用户名字段为
felhasznalonev,但UserRepository中定义的查询方法为findByUsername,JPA无法匹配到对应字段,后续即使解决栈溢出也会查询不到用户。
解决方案
第一步:修改SecurityConfig配置
删除以下冗余代码:
@Autowired private UserDetailsService userDetailsService; @Bean @Override public UserDetailsService userDetailsService() { return super.userDetailsService(); }
修改配置类,直接注入你自定义的UserDetailsService实现即可,修改后核心代码参考:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { // 直接注入你自己实现的UserDetailsService private final UserServiceImpl userDetailsService; public SecurityConfig(UserServiceImpl userDetailsService) { this.userDetailsService = userDetailsService; } @Override public void configure(AuthenticationManagerBuilder auth) throws Exception{ auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); } // 原有http配置、PasswordEncoder的Bean定义保留即可 @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .anyRequest() .authenticated() .and() .formLogin() .permitAll(); } @Bean public PasswordEncoder passwordEncoder() {return NoOpPasswordEncoder.getInstance();} }
第二步:修正JPA查询方法
将UserRepository中的方法名改为和实体字段匹配的命名:
public interface UserRepository extends JpaRepository<User,Integer> { // 实体用户名字段是felhasznalonev,JPA查询方法需要和字段名对应 User findByFelhasznalonev(String felhasznalonev); }
同时对应修改UserServiceImpl里的调用逻辑:
@Override public User findByUsername(String username) { return userRepository.findByFelhasznalonev(username); }
内容的提问来源于stack exchange,提问作者magyartesco
相关产品推荐
相关产品推荐

