{"record":{"id":"d83328b4cce2e855","repo":"spring-projects/spring-security","slug":"empty-password","errorCode":null,"errorMessage":"Empty Password","messagePattern":"Empty Password","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":null,"severity":"error","filePath":"ldap/src/main/java/org/springframework/security/ldap/authentication/AbstractLdapAuthenticationProvider.java","lineNumber":79,"sourceCode":"\n\tprivate GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();\n\n\tprotected UserDetailsContextMapper userDetailsContextMapper = new LdapUserDetailsMapper();\n\n\t@Override\n\tpublic Authentication authenticate(Authentication authentication) throws AuthenticationException {\n\t\tAssert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication,\n\t\t\t\t() -> this.messages.getMessage(\"LdapAuthenticationProvider.onlySupports\",\n\t\t\t\t\t\t\"Only UsernamePasswordAuthenticationToken is supported\"));\n\t\tUsernamePasswordAuthenticationToken userToken = (UsernamePasswordAuthenticationToken) authentication;\n\t\tString username = userToken.getName();\n\t\tString password = (String) authentication.getCredentials();\n\t\tif (!StringUtils.hasLength(username)) {\n\t\t\tthrow new BadCredentialsException(\n\t\t\t\t\tthis.messages.getMessage(\"LdapAuthenticationProvider.emptyUsername\", \"Empty Username\"));\n\t\t}\n\t\tif (!StringUtils.hasLength(password)) {\n\t\t\tthrow new BadCredentialsException(\n\t\t\t\t\tthis.messages.getMessage(\"AbstractLdapAuthenticationProvider.emptyPassword\", \"Empty Password\"));\n\t\t}\n\t\tAssert.notNull(password, \"Null password was supplied in authentication token\");\n\t\tDirContextOperations userData = doAuthentication(userToken);\n\t\tUserDetails user = this.userDetailsContextMapper.mapUserFromContext(userData, authentication.getName(),\n\t\t\t\tloadUserAuthorities(userData, authentication.getName(), password));\n\t\treturn createSuccessfulAuthentication(userToken, user);\n\t}\n\n\tprotected abstract DirContextOperations doAuthentication(UsernamePasswordAuthenticationToken auth);\n\n\tprotected abstract Collection<? extends GrantedAuthority> loadUserAuthorities(DirContextOperations userData,\n\t\t\tString username, String password);\n\n\t/**\n\t * Creates the final {@code Authentication} object which will be returned from the\n\t * {@code authenticate} method.\n\t * @param authentication the original authentication request token","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/ldap/src/main/java/org/springframework/security/ldap/authentication/AbstractLdapAuthenticationProvider.java#L61-L97","documentation":"AbstractLdapAuthenticationProvider.authenticate() throws BadCredentialsException('Empty Password') when the credentials of the UsernamePasswordAuthenticationToken are null or blank. Many LDAP directories (notably Active Directory) treat an empty password bind as an unauthenticated bind, so the provider refuses it up front.","triggerScenarios":"Submitting a login token with null/empty credentials: an empty password field on the login form, a JSON body missing the password key, or a custom filter that forgot to set credentials when constructing UsernamePasswordAuthenticationToken.","commonSituations":"Password field omitted in REST payloads, form auto-submit before the user typed the password, AD environment where an empty bind would silently succeed, or password stripped by an upstream filter.","solutions":["Validate the password is non-blank before invoking the AuthenticationManager and return a 400/validation error.","Check your request mapping/binding actually extracts the password field (correct JSON property or form parameter name).","If using a custom authentication filter, ensure you pass the password as the credentials argument to the token constructor.","Never send empty-password binds to LDAP — this guard exists to prevent anonymous-bind style logins."],"exampleFix":"// before\nAuthentication auth = new UsernamePasswordAuthenticationToken(username, request.getParameter(\"pwd\")); // null key\nmanager.authenticate(auth); // Empty Password\n\n// after\nString pwd = request.getParameter(\"password\");\nif (pwd == null || pwd.isEmpty()) {\n    throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"password is required\");\n}\nAuthentication auth = new UsernamePasswordAuthenticationToken(username, pwd);\nmanager.authenticate(auth);","handlingStrategy":"validation","validationCode":"if (password == null || password.isEmpty()) {\n    throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"password is required\");\n}","typeGuard":"static boolean hasCredentials(UsernamePasswordAuthenticationToken t) {\n    return t != null && t.getCredentials() instanceof String s && !s.isEmpty();\n}","tryCatchPattern":"try {\n    return authManager.authenticate(token);\n} catch (BadCredentialsException e) {\n    if (\"Empty Password\".equals(e.getMessage())) {\n        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"password is required\");\n    }\n    throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, \"invalid credentials\");\n}","preventionTips":["Validate the password field is present before hitting the AuthenticationManager.","Ensure JSON binding maps the password property correctly (missing keys become null).","Guard against empty-password binds explicitly — especially on Active Directory.","Use @NotBlank on credentials fields in login DTOs."],"tags":["ldap","authentication","empty-password","input-validation"],"backgroundTag":"empty-required-field","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}