{"record":{"id":"463b316b72874972","repo":"macrozheng/mall-learning","slug":"error-463b31","errorCode":null,"errorMessage":"密码不正确","messagePattern":"密码不正确","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":null,"severity":"error","filePath":"mall-tiny-08/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-08/src/main/java/com/macro/mall/tiny/service/impl/UmsAdminServiceImpl.java#L88-L117","documentation":"mall-tiny-08's login() throws BadCredentialsException('密码不正确') when passwordEncoder.matches fails — the provided password does not correspond to the stored BCrypt hash for that admin. The surrounding catch(AuthenticationException) logs '登录异常' and returns the empty token, hiding the failure from the caller.","triggerScenarios":"POST /admin/login (or login() call) with correct username and wrong password; matches() returns false and the exception is thrown.","commonSituations":"Password typo, seed users with plaintext or MD5 passwords instead of BCrypt, PasswordEncoder bean changed after user creation, direct DB password edits, copied user rows across environments with different passwords.","solutions":["Reset the password with a BCrypt-encoded hash matching the configured encoder","Verify stored hashes are BCrypt format ($2a$/$2b$...)","Ensure the same PasswordEncoder is used for register and login","Improve error surfacing: propagate BadCredentialsException as a proper API error"],"exampleFix":"// before\nif (!passwordEncoder.matches(password, userDetails.getPassword())) {\n    throw new BadCredentialsException(\"密码不正确\");\n}\n// after\nif (!passwordEncoder.matches(password, userDetails.getPassword())) {\n    log.warn(\"Invalid password for user: {}\", username);\n    throw new BadCredentialsException(\"密码不正确\");\n}","handlingStrategy":"try-catch","validationCode":"if (password == null || password.isEmpty()) return CommonResult.validateFailed(\"密码不能为空\");\nString stored = userDetails != null ? userDetails.getPassword() : null;\nif (stored != null && !stored.startsWith(\"$2\")) log.error(\"Stored password not BCrypt: {}\", username);","typeGuard":null,"tryCatchPattern":"try {\n    String token = adminService.login(username, password);\n} catch (BadCredentialsException e) {\n    log.warn(\"登录异常:{}\", e.getMessage());\n    return CommonResult.failed(\"用户名或密码错误\");\n}","preventionTips":["Encode every password with passwordEncoder.encode() at creation","Match the encoder between register and login paths","Avoid manual DB password updates without re-encoding","Distinguish empty-token (unknown user) vs wrong-password cases in logs"],"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"}