{"record":{"id":"78169c7281b0a945","repo":"spring-projects/spring-security","slug":"empty-username","errorCode":null,"errorMessage":"Empty Username","messagePattern":"Empty Username","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":null,"severity":"error","filePath":"ldap/src/main/java/org/springframework/security/ldap/authentication/AbstractLdapAuthenticationProvider.java","lineNumber":75,"sourceCode":"\n\tprotected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();\n\n\tprivate boolean useAuthenticationRequestCredentials = true;\n\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","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/ldap/src/main/java/org/springframework/security/ldap/authentication/AbstractLdapAuthenticationProvider.java#L57-L93","documentation":"AbstractLdapAuthenticationProvider.authenticate() rejects a UsernamePasswordAuthenticationToken whose username is null or blank by throwing BadCredentialsException('Empty Username') before any LDAP call is made. The library treats missing identity as bad credentials rather than a server error.","triggerScenarios":"Submitting an Authentication to an LdapAuthenticationProvider-backed AuthenticationManager where authentication.getName() is empty — e.g. a login form posted with an empty username field, or a custom Authentication token constructed with a null/blank principal.","commonSituations":"Frontend allowed empty form submission, API clients omitting the username field in a JSON login payload, custom filters creating UsernamePasswordAuthenticationToken without validating the principal, or whitespace-only input.","solutions":["Validate the username is non-blank in your controller/filter before building the authentication token.","Return a friendly client-side validation error instead of hitting the AuthenticationManager.","If the empty value comes from form binding, configure the binder/filter to reject blank fields early.","Ensure you are not accidentally passing credentials as the principal (wrong constructor argument order)."],"exampleFix":"// before\nAuthentication auth = new UsernamePasswordAuthenticationToken(request.getParameter(\"user\"), request.getParameter(\"pass\"));\nmanager.authenticate(auth); // Empty Username\n\n// after\nString user = request.getParameter(\"user\");\nif (user == null || user.isBlank()) {\n    throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"username is required\");\n}\nAuthentication auth = new UsernamePasswordAuthenticationToken(user, request.getParameter(\"pass\"));\nmanager.authenticate(auth);","handlingStrategy":"validation","validationCode":"if (username == null || username.isBlank()) {\n    throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"username is required\");\n}","typeGuard":"static boolean hasUsername(UsernamePasswordAuthenticationToken t) {\n    return t != null && t.getName() != null && !t.getName().isBlank();\n}","tryCatchPattern":"try {\n    return authManager.authenticate(token);\n} catch (BadCredentialsException e) {\n    if (\"Empty Username\".equals(e.getMessage())) {\n        throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"username is required\");\n    }\n    throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, \"invalid credentials\");\n}","preventionTips":["Enforce required-field validation at the controller/DTO layer before authentication.","Add @NotBlank constraints on login DTO fields.","Never construct authentication tokens from unvalidated request parameters.","Check constructor argument order (principal first, credentials second)."],"tags":["ldap","authentication","empty-username","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-14T11:17:12.474Z"}