macrozheng/mall-learning · error · BadCredentialsException

密码不正确

Error message

密码不正确

What it means

UmsAdminServiceImpl.login throws BadCredentialsException('密码不正确') when passwordEncoder.matches(password, userDetails.getPassword()) fails — i.e. the submitted BCrypt hash does not match the stored hash. This is Spring Security's standard signal for a wrong password during programmatic login. Note the catch block immediately swallows it (catch AuthenticationException) and returns an empty token, so callers often see null/empty token instead of the exception itself.

Solutions

  1. Re-enter/reset the password; reset via UPDATE ums_admin SET password = '{bcrypt}...' with a properly BCrypt-encoded value
  2. Verify stored passwords are BCrypt-encoded (start with $2a$/$2b$); re-encode seed data if not
  3. Confirm the PasswordEncoder bean matches how passwords were created (same encoder for register and login)
  4. Check that the catch block does not silently mask the failure; log/return a clear error to the caller

Example fix

// before
if (!passwordEncoder.matches(password, userDetails.getPassword())) {
    throw new BadCredentialsException("密码不正确");
}
// after
if (!passwordEncoder.matches(password, userDetails.getPassword())) {
    log.warn("Wrong password for user: {}", username);
    throw new BadCredentialsException("密码不正确");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side: require non-empty password before submit
if (!password || password.length < 6) throw new Error('密码不能为空');
// server-side sanity: stored hash must look like BCrypt
String stored = userDetails.getPassword();
boolean looksBcrypt = stored != null && (stored.startsWith("$2a$") || stored.startsWith("$2b$") || stored.startsWith("{bcrypt}"));
if (!looksBcrypt) log.error("Stored password for {} is not BCrypt-encoded", username);

Try / catch

try {
    String token = adminService.login(username, password);
    if (token == null || token.isEmpty()) {
        throw new ApiException("用户名或密码错误");
    }
} catch (BadCredentialsException e) {
    throw new ApiException("密码不正确");
}

Prevention

When it happens

Trigger: POST /admin/login with a valid username but a password whose BCrypt hash does not match ums_admin.password.

Common situations: User typo in password, admin row created with a plaintext or differently-encoded password (so BCrypt matches always fail), seed data inserted without BCrypt encoding, password changed in DB directly, wrong encoder bean configured (e.g. changing PasswordEncoder after users were created).

Related errors


AI-assisted analysis of macrozheng/mall-learning@cd02c000e5 (2026-09-07). Data as JSON: /api/errors/5673f766b383d55b. Report an issue: GitHub.

Appendix: source

Thrown at mall-tiny-04/src/main/java/com/macro/mall/tiny/service/impl/UmsAdminServiceImpl.java:106

        }
        return null;
    }

    @Override
    public List<UmsResource> getResourceList() {
        return resourceList;
    }

    @Override
    public String login(String username, String password) {
        String token = null;
        try {
            UserDetails userDetails = getAdminByUsername(username);
            if(userDetails==null){
                return token;
            }
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                throw new BadCredentialsException("密码不正确");
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails);
        } catch (AuthenticationException e) {
            log.warn("登录异常:{}", e.getMessage());
        }
        return token;
    }
}

View on GitHub (pinned to cd02c000e5)