首页 文章

使用Spring Data REST进行密码编码

提问于
浏览
4

我应该如何使用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
  ...
}

首先我尝试使用@HandleBeforeCreate和@HandleBeforeSave事件侦听器解决但是其中的用户参数已经合并,因此我无法区分用户的新密码或旧密码哈希:

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

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

2 回答

  • 0

    您可以实现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;
        }
    }
    

    并将其应用于您的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;
    
  • 7

    修改密码字段的setter方法就足够了,如下所示:

    public void setPassword(String password) {
            PasswordEncoder encoder = new BCryptPasswordEncoder();
            this.password = encoder.encode(password);
        }
    

    参考:https://github.com/charybr/spring-data-rest-acl/blob/master/bookstore/src/main/java/sample/sdr/auth/bean/UserEntity.java

相关问题