Search code examples
springspring-bootvalidationspring-security

Why Spring password validator is not working?


I want to make a password validator, in which password should have at least 1 uppercase,1 lowercase and 1 special, no whitespace. I passed through postman password "123" and I got Http 200.OK, but I should not have since it violates my password validator. Here is my code: Dto request:

@Data
@AllArgsConstructor
public class UserRegistrationDtoRequest {
    @NotNull
    private String email;
    @ValidPassword
    private String password;
    
    private String address;

}

Valid password annotation:

@Documented
@Constraint(validatedBy = PasswordConstraintValidator.class)
@Target({ElementType.TYPE,ElementType.FIELD,ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPassword {
    String message() default "Invalid password.Password should have at least 8 characters";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

}

ConstraintValidator implementation:

public class PasswordConstraintValidator implements ConstraintValidator<ValidPassword,String> {
    @Override
    public void initialize(ValidPassword constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        PasswordValidator validator = new PasswordValidator(Arrays.asList(
                new LengthRule(8,20),
                new CharacterRule(EnglishCharacterData.UpperCase,1),
                new CharacterRule(EnglishCharacterData.LowerCase,5),
                new CharacterRule(EnglishCharacterData.Special,1),
                new WhitespaceRule()));
        RuleResult ruleResult = validator.validate(new PasswordData(value));
        if(ruleResult.isValid()){
            return true;
        }
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(
                validator.getMessages(ruleResult).toString()).addConstraintViolation();
        return false;
    }
}

Solution

  • The spring boot validation is working with @Valid annotation provided by javax.

    @PostMapping("${endpoint.api.signup}")
      public ResponseEntity<Boolean> signup(@RequestBody @Valid UserRegistrationDtoRequest registrationDTO) {
        log.info("Request to register user: {}", registrationDTO.getUsername());
        userService.register(registrationDTO);
        return ResponseEntity.ok(true);
      }