使用Spring Data REST进行密码编码

Plu*_*toz 4 spring-data-rest

我应该如何使用Spring Data REST自动编码实体的subbmitted plain password字段?

我正在使用BCrypt编码器,当客户端通过POST,PUT和PATCH发送请求时,我想自动编码请求的密码字段.

@Entity
public class User {
  @NotNull
  private String username;
  @NotNull
  private String passwordHash;
  ...
  getters/setters/etc
  ...
}
Run Code Online (Sandbox Code Playgroud)

首先我尝试使用@HandleBeforeCreate和@HandleBeforeSave事件侦听器解决但是其中的用户参数已经合并,所以我不能在用户的新密码或旧密码哈希之间有任何区别:

@HandleBeforeSave
protected void onBeforeSave(User user) {
    if (user.getPassword() != null) {
        account.setPassword(passwordEncoder.encode(account.getPassword()));
    }
    super.onBeforeSave(account);
}
Run Code Online (Sandbox Code Playgroud)

这是可能的,在setter方法上使用@Projection和SpEL吗?

rob*_*lls 8

您可以实现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;
    }
}
Run Code Online (Sandbox Code Playgroud)

并将其应用于您的JPA实体属性:

// 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;
Run Code Online (Sandbox Code Playgroud)