{"record":{"id":"5673f766b383d55b","repo":"macrozheng/mall-learning","slug":"error-5673f7","errorCode":null,"errorMessage":"密码不正确","messagePattern":"密码不正确","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":null,"severity":"error","filePath":"mall-tiny-04/src/main/java/com/macro/mall/tiny/service/impl/UmsAdminServiceImpl.java","lineNumber":106,"sourceCode":"        }\n        return null;\n    }\n\n    @Override\n    public List<UmsResource> getResourceList() {\n        return resourceList;\n    }\n\n    @Override\n    public String login(String username, String password) {\n        String token = null;\n        try {\n            UserDetails userDetails = getAdminByUsername(username);\n            if(userDetails==null){\n                return token;\n            }\n            if (!passwordEncoder.matches(password, userDetails.getPassword())) {\n                throw new BadCredentialsException(\"密码不正确\");\n            }\n            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());\n            SecurityContextHolder.getContext().setAuthentication(authentication);\n            token = jwtTokenUtil.generateToken(userDetails);\n        } catch (AuthenticationException e) {\n            log.warn(\"登录异常:{}\", e.getMessage());\n        }\n        return token;\n    }\n}\n","sourceCodeStart":88,"sourceCodeEnd":117,"githubUrl":"https://github.com/macrozheng/mall-learning/blob/cd02c000e57c693e49f1f72986dbfa6e4c952e09/mall-tiny-04/src/main/java/com/macro/mall/tiny/service/impl/UmsAdminServiceImpl.java#L88-L117","documentation":"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.","triggerScenarios":"POST /admin/login with a valid username but a password whose BCrypt hash does not match ums_admin.password.","commonSituations":"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).","solutions":["Re-enter/reset the password; reset via UPDATE ums_admin SET password = '{bcrypt}...' with a properly BCrypt-encoded value","Verify stored passwords are BCrypt-encoded (start with $2a$/$2b$); re-encode seed data if not","Confirm the PasswordEncoder bean matches how passwords were created (same encoder for register and login)","Check that the catch block does not silently mask the failure; log/return a clear error to the caller"],"exampleFix":"// before\nif (!passwordEncoder.matches(password, userDetails.getPassword())) {\n    throw new BadCredentialsException(\"密码不正确\");\n}\n// after\nif (!passwordEncoder.matches(password, userDetails.getPassword())) {\n    log.warn(\"Wrong password for user: {}\", username);\n    throw new BadCredentialsException(\"密码不正确\");\n}","handlingStrategy":"try-catch","validationCode":"// client-side: require non-empty password before submit\nif (!password || password.length < 6) throw new Error('密码不能为空');\n// server-side sanity: stored hash must look like BCrypt\nString stored = userDetails.getPassword();\nboolean looksBcrypt = stored != null && (stored.startsWith(\"$2a$\") || stored.startsWith(\"$2b$\") || stored.startsWith(\"{bcrypt}\"));\nif (!looksBcrypt) log.error(\"Stored password for {} is not BCrypt-encoded\", username);","typeGuard":null,"tryCatchPattern":"try {\n    String token = adminService.login(username, password);\n    if (token == null || token.isEmpty()) {\n        throw new ApiException(\"用户名或密码错误\");\n    }\n} catch (BadCredentialsException e) {\n    throw new ApiException(\"密码不正确\");\n}","preventionTips":["Always encode passwords with the same PasswordEncoder used at login","Never insert plaintext or MD5 passwords into ums_admin","If you change the encoder, migrate all stored hashes","Don't silently swallow AuthenticationException in login(); return a clear error","Wrap DB-edited passwords with {bcrypt} prefix or re-encode them"],"tags":["spring-security","bcrypt","authentication","login"],"backgroundTag":"invalid-credentials","analyzedSha":"cd02c000e57c693e49f1f72986dbfa6e4c952e09","analyzedAt":"2026-09-07T23:16:08.059Z","contentChangedAt":"2026-09-07T23:16:08.059Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}