4

I'm pulling my hair out over this. I have a simple User entity like this

@Entity
public class User {
  private static final PasswordEncoder pwEncoder = new BCryptPasswordEncoder();

  @Id 
  @GeneratedValue 
  private long id;

  @NotNull(message = "FIELD_IS_NULL")
  @NotEmpty(message = "FIELD_IS_REQUIRED")
  @Length(min = 3, message = "FIELD_MUST_HAVE_AT_LEAST_3_CHARACTERS")
  private String username;

  @NotNull(message = "FIELD_IS_NULL")
  @NotEmpty(message = "FIELD_IS_REQUIRED")
  @Length(min = 6, message = "FIELD_MUST_HAVE_AT_LEAST_6_CHARACTERS")
  @Pattern(regexp = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{6,128}$", message="PW_MIN_6_MAX_128_1_UPPER_1_LOWER_1_NUMERIC")
  private String password;

  public User(String username, String password){
    this.username = username;
    this.password = pwEncoder.encode(password);
  }

  /* getters and setters */
}

This works fine except that the password hashing happens before any validation, which means that the hashed password is validated instead of the unhashed.

I'm using a PagingAndSortingRepository for all my repository needs and I'd really like to avoid implementing a controller just for this case.

I'm feeling like I'm missing something really big there...

4
  • It's not encryption, it's hashing. You're supposed to compare the hashes, so you don't store the original password in plaintext. Don't apply validation to the hash, that doesn't make sense. Commented Oct 31, 2017 at 15:13
  • Of course you're right about hashing vs encryption. But how can I apply validation to the password and not the hash? Commented Oct 31, 2017 at 15:17
  • I'm not sure, entity class is good place for such algorithms? Commented Oct 31, 2017 at 15:19
  • 1
    Apply it at the controller level, not the persistence level - it should be a bad request if the password doesn't meet the requirements. Commented Oct 31, 2017 at 15:19

1 Answer 1

4

If you using this constructor

public User(String username, String password){
    this.username = username;
    this.password = pwEncoder.encode(password);
}

you'll have encoded password instead of original value

you can make @PrePersist method like this:

@PrePersist
public void prePersist(){
    password = pwEncoder.encode(password);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.