{"record":{"id":"dcdb7b8977797a73","repo":"xkcoding/spring-boot-demo","slug":"error","errorCode":null,"errorMessage":"用户名或密码错误，请重新尝试","messagePattern":"用户名或密码错误，请重新尝试","errorType":"exception","errorClass":"ServiceException","httpStatus":null,"severity":"warning","filePath":"demo-ldap/src/main/java/com/xkcoding/ldap/service/impl/PersonServiceImpl.java","lineNumber":45,"sourceCode":"@RequiredArgsConstructor(onConstructor_ = @Autowired)\npublic class PersonServiceImpl implements PersonService {\n    private final PersonRepository personRepository;\n\n    /**\n     * 登录\n     *\n     * @param request {@link LoginRequest}\n     * @return {@link Result}\n     */\n    @Override\n    public Result login(LoginRequest request) {\n        log.info(\"IN LDAP auth\");\n\n        Person user = personRepository.findByUid(request.getUsername());\n\n        try {\n            if (ObjectUtils.isEmpty(user)) {\n                throw new ServiceException(\"用户名或密码错误，请重新尝试\");\n            } else {\n                user.setUserPassword(LdapUtils.asciiToString(user.getUserPassword()));\n                if (!LdapUtils.verify(user.getUserPassword(), request.getPassword())) {\n                    throw new ServiceException(\"用户名或密码错误，请重新尝试\");\n                }\n            }\n        } catch (NoSuchAlgorithmException e) {\n            e.printStackTrace();\n        }\n\n        log.info(\"user info:{}\", user);\n        return Result.success(user);\n    }\n\n    /**\n     * 查询全部\n     *\n     * @return {@link Result}","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/xkcoding/spring-boot-demo/blob/87a142f9604c1a5365b4d24d22c2c11c26a9d5ab/demo-ldap/src/main/java/com/xkcoding/ldap/service/impl/PersonServiceImpl.java#L27-L63","documentation":"Thrown during LDAP login when personRepository.findByUid(username) returns an empty/null Person — the uid does not exist in the LDAP directory. The message deliberately says 'username or password incorrect' rather than 'user not found' to prevent user-enumeration attacks (a common security best practice). The ServiceException is a RuntimeException.","triggerScenarios":"POST to the login endpoint with a username that does not match any uid in the LDAP directory. ObjectUtils.isEmpty(user) evaluates true because findByUid returns null for a non-existent uid.","commonSituations":"User mistyped their uid; the LDAP directory has not been populated with the user entry; the LDAP server connection succeeded but the search base DN is wrong so no entries are found; case sensitivity mismatch on uid.","solutions":["Verify the user's uid exists in the LDAP directory using an LDAP browser (e.g., Apache Directory Studio) or ldapsearch.","Check the Spring LDAP context-source base DN configuration matches the directory structure.","Confirm uid attribute case matches the stored value (LDAP uid is often case-sensitive).","Ensure the login form sends the correct field mapped to request.getUsername()."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Validate username is non-empty before calling login\nif (StrUtil.isBlank(request.getUsername())) {\n    return Result.fail(\"用户名不能为空\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    Result result = personService.login(request);\n    return result;\n} catch (ServiceException e) {\n    // Both 'user not found' and 'wrong password' produce the same message — do not distinguish\n    log.warn(\"LDAP login failed for username={}\", request.getUsername());\n    return Result.fail(e.getMessage());\n}","preventionTips":["Always return a generic 'username or password incorrect' message to prevent user enumeration.","Log the actual failure reason server-side for debugging while keeping client messages generic.","Validate input format (non-blank username) before hitting the LDAP directory."],"tags":["ldap","authentication","login","security","spring-ldap"],"backgroundTag":null,"analyzedSha":"87a142f9604c1a5365b4d24d22c2c11c26a9d5ab","analyzedAt":"2026-08-14T01:16:58.217Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}