Spring Boot 3 JWT认证时出现BadCredentials错误求助
问题排查与解决方案
核心问题:密码重复加密导致验证失败
你的UserDetailsService实现存在致命错误:每次加载用户信息时,都会对数据库中已经加密过的密码再次执行BCryptPasswordEncoder.encode(),导致UserDetails对象中的密码是双重加密后的结果,与前端传入的原始密码(仅需一次加密匹配)无法对应,最终触发BadCredentialsException。
错误代码片段:
@Bean fun userDetailsService(): UserDetailsService = UserDetailsService { username -> val userDetail: UserDetails runBlocking { val user = service.getUser(email = username) ?: throw UsernameNotFoundException("Email address is Invalid") // 错误:数据库中的user.loginPassword已是加密后的,此处再次加密 userDetail = User.withUsername(user.email).password(getPasswordEncoder().encode(user.loginPassword)).build() } userDetail }
修复方案
1. 修正UserDetailsService实现
直接使用数据库中存储的加密密码,不再二次加密:
@Bean fun userDetailsService(): UserDetailsService = UserDetailsService { username -> val userDetail: UserDetails runBlocking { val user = service.getUser(email = username) ?: throw UsernameNotFoundException("Email address is Invalid") // 直接复用数据库中已加密的密码 userDetail = User.withUsername(user.email).password(user.loginPassword).build() } userDetail }
2. 确认注册逻辑正确性
确保用户注册时,密码仅被加密一次后存入数据库,示例代码:
// 注册接口中处理密码的逻辑 val encryptedPassword = getPasswordEncoder().encode(userInput.rawPassword) // 将encryptedPassword存入user.loginPassword字段
额外检查项
- 确认
SecurityConfiguration中/auth/**路径已正确配置permitAll(),避免登录请求被拦截。 - 验证登录请求的
Content-Type为application/json,且请求体字段与LoginDTO定义完全匹配。
内容的提问来源于stack exchange,提问作者OmniCoder77
相关产品推荐
相关产品推荐

