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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:08:13