How should I encode automatically the subbmitted plain password field of my entity with Spring Data REST?
I\'m using BCrypt encoder and I want to automatically encod
You can implement a Jackson JsonDeserializer:
public class BCryptPasswordDeserializer extends JsonDeserializer<String> {
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
ObjectCodec oc = jsonParser.getCodec();
JsonNode node = oc.readTree(jsonParser);
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String encodedPassword = encoder.encode(node.asText());
return encodedPassword;
}
}
And apply it to your JPA Entity property:
// The value of the password will always have a length of
// 60 thanks to BCrypt
@Size(min = 60, max = 60)
@Column(name="password", nullable = false, length = 60)
@JsonDeserialize(using = BCryptPasswordDeserializer.class )
private String password;
Some enhancement to @robgmills JsonDeserializer
solution:
DelegatingPasswordEncoder
. It is more flexible, see spring docs.PasswordEncoder
every time at deserialization.JsonDeserializer
's - better make them inner classes.@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
, see https://stackoverflow.com/a/12505165/548473For Spring Boot code looks like:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public static final PasswordEncoder PASSWORD_ENCODER = PasswordEncoderFactories.createDelegatingPasswordEncoder();
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).passwordEncoder(PASSWORD_ENCODER);
}
....
public class JsonDeserializers {
public static class PasswordDeserializer extends JsonDeserializer<String> {
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
ObjectCodec oc = jsonParser.getCodec();
JsonNode node = oc.readTree(jsonParser);
String rawPassword = node.asText();
return WebSecurityConfig.PASSWORD_ENCODER.encode(rawPassword);
}
}
...
@Entity
public class User ...
@Column(name = "password")
@Size(max = 256)
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@JsonDeserialize(using = JsonDeserializers.PasswordDeserializer.class)
private String password;
...
Modifying setter method of password field is sufficient, as shown below:
public void setPassword(String password) {
PasswordEncoder encoder = new BCryptPasswordEncoder();
this.password = encoder.encode(password);
}
Refer: https://github.com/charybr/spring-data-rest-acl/blob/master/bookstore/src/main/java/sample/sdr/auth/bean/UserEntity.java