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

Spring Boot登录REST API报500错误及BadCredentialsException问题排查

解决Spring Boot登录API的BadCredentialsException及500错误问题

以下是针对性的排查和解决步骤:

1. 校验请求参数与数据库数据的一致性

  • 检查Postman发送的usernameOrEmail和password是否与数据库存储的完全匹配,注意大小写敏感、首尾空格等细节(比如密码输入时不小心带了空格)
  • 如果数据库中密码是加密存储的,确认登录时Postman发送的是明文密码(Spring Security会自动完成加密比对,不需要手动加密)

2. 确保UserDetailsService实现正确

你需要自定义UserDetailsService来根据用户名/邮箱查询用户,确保返回的UserDetails对象包含正确的加密密码和权限。示例实现:

@Service
public class CustomUserDetailsService implements UserDetailsService {

    private final UserRepository userRepository;

    public CustomUserDetailsService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException {
        User user = userRepository.findByUsernameOrEmail(usernameOrEmail, usernameOrEmail)
                .orElseThrow(() -> new UsernameNotFoundException("用户不存在: " + usernameOrEmail));
        
        return User.builder()
                .username(user.getUsername())
                .password(user.getPassword()) // 必须是数据库中存储的加密后的密码
                .authorities(user.getRoles().stream()
                        .map(role -> new SimpleGrantedAuthority(role.getName()))
                        .collect(Collectors.toList()))
                .build();
    }
}

3. 正确配置AuthenticationManager Bean

确保Spring Security配置类中暴露了AuthenticationManager的Bean,否则注入的管理器无法正常工作:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

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

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

    // 放行登录接口等基础配置
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/api/auth/**").permitAll()
                        .anyRequest().authenticated());
        return http.build();
    }
}

4. 捕获异常,返回合理的HTTP状态码

当前代码未处理BadCredentialsException,导致Spring返回500内部错误。应该捕获该异常,返回401 Unauthorized更符合REST规范:

方式1:在控制器中直接捕获

@PostMapping("/login")
public ResponseEntity<String> login(@RequestBody LoginDto loginDto){
    try {
        String response = authService.login(loginDto);
        return ResponseEntity.ok(response);
    } catch (BadCredentialsException e) {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用户名或密码错误");
    }
}

方式2:全局异常处理器(推荐)

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(BadCredentialsException.class)
    public ResponseEntity<String> handleBadCredentialsException(BadCredentialsException ex) {
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用户名或密码不正确");
    }
}

5. 确认密码加密方式一致

注册用户时,必须使用与Security配置中相同的PasswordEncoder加密密码后再存入数据库:

@Service
public class AuthServiceImpl implements AuthService {
    private final AuthenticationManager authenticationManager;
    private final PasswordEncoder passwordEncoder;
    private final UserRepository userRepository;

    public AuthServiceImpl(AuthenticationManager authenticationManager, PasswordEncoder passwordEncoder, UserRepository userRepository) {
        this.authenticationManager = authenticationManager;
        this.passwordEncoder = passwordEncoder;
        this.userRepository = userRepository;
    }

    // 注册方法示例
    public String register(RegisterDto registerDto) {
        User user = new User();
        user.setUsername(registerDto.getUsername());
        user.setEmail(registerDto.getEmail());
        // 加密密码后存入数据库
        user.setPassword(passwordEncoder.encode(registerDto.getPassword()));
        user.setRoles(Collections.singletonList(new Role("ROLE_USER")));
        userRepository.save(user);
        return "用户注册成功";
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:53:13