Spring Boot 3.0.6创建用户时PasswordEncoder空指针异常求助
问题:创建新用户时出现PasswordEncoder空指针异常
错误信息
{"message": "Cannot invoke \"org.springframework.security.crypto.password.PasswordEncoder.encode(java.lang.CharSequence)\" because \"this.passwordEncoder\" is null", "path": "/auth/nuevo"}
我的MainSecurity代码
@Configuration @EnableWebSecurity @EnableMethodSecurity public class MainSecurity { @Autowired UserDetailsImpl userDetailsServiceImpl; @Autowired JwtEntryPoint jwtEntryPoint; @Bean public JwtTokenFilter jwtTokenFilter() { return new JwtTokenFilter(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsServiceImpl).passwordEncoder(passwordEncoder()); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.cors().and().csrf().disable() .exceptionHandling().authenticationEntryPoint(jwtEntryPoint).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeHttpRequests() .requestMatchers("/**").permitAll() .anyRequest().authenticated(); http .addFilterBefore(jwtTokenFilter() , UsernamePasswordAuthenticationFilter.class); return http.build(); } }
解决方案
1. 修复用户创建Service的PasswordEncoder注入
空指针的核心原因是创建用户的逻辑中未正确注入PasswordEncoder Bean,导致调用encode方法时对象为空。确保用户Service通过构造注入(Spring 3.x推荐方式)引入PasswordEncoder:
@Service public class UserService { private final PasswordEncoder passwordEncoder; private final UserRepository userRepository; public UserService(PasswordEncoder passwordEncoder, UserRepository userRepository) { this.passwordEncoder = passwordEncoder; this.userRepository = userRepository; } public User createUser(UserDto userDto) { User user = new User(); user.setUsername(userDto.getUsername()); // 使用注入的PasswordEncoder加密密码 user.setPassword(passwordEncoder.encode(userDto.getPassword())); // 其他字段赋值 return userRepository.save(user); } }
2. 移除已弃用的configure方法
Spring Boot 3.x中configure(AuthenticationManagerBuilder auth)方法已被弃用,框架会自动关联你定义的PasswordEncoder和UserDetailsService Bean,无需手动配置。修改后的MainSecurity代码:
@Configuration @EnableWebSecurity @EnableMethodSecurity public class MainSecurity { private final UserDetailsImpl userDetailsServiceImpl; private final JwtEntryPoint jwtEntryPoint; // 构造注入替代@Autowired(Spring 3.x推荐写法) public MainSecurity(UserDetailsImpl userDetailsServiceImpl, JwtEntryPoint jwtEntryPoint) { this.userDetailsServiceImpl = userDetailsServiceImpl; this.jwtEntryPoint = jwtEntryPoint; } @Bean public JwtTokenFilter jwtTokenFilter() { return new JwtTokenFilter(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.cors().and().csrf().disable() .exceptionHandling().authenticationEntryPoint(jwtEntryPoint).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeHttpRequests(auth -> auth .requestMatchers("/**").permitAll() .anyRequest().authenticated()) .addFilterBefore(jwtTokenFilter(), UsernamePasswordAuthenticationFilter.class); return http.build(); } }
3. 验证UserDetailsImpl的配置
确保UserDetailsImpl类正确实现UserDetailsService接口,并且添加了@Service注解被Spring容器管理。
内容的提问来源于stack exchange,提问作者Programmer-G
相关产品推荐
相关产品推荐

