Fabian
Fabian

Reputation: 183

Java Spring hash AND validate passwords

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...

Upvotes: 4

Views: 1472

Answers (1)

Yegor Babarykin
Yegor Babarykin

Reputation: 705

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);
}

Upvotes: 4

Related Questions