【发布时间】:2016-05-05 23:23:44
【问题描述】:
我有以下实体:
@Entity
public class User {
@Id
private Integer id;
private String username;
private String password;
}
要设置密码,必须提供明文密码,但实际存储的密码是明文密码的哈希值。问题是实际的哈希计算取决于业务。更具体地说,我有以下接口和 Session Bean:
public interface PasswordHash {
String hash(String password);
}
@Stateless
public class UserManager {
@Inject
private PasswordHash phash;
public void changeUserPassword(User user, String newPassword) {
String passwordHash = phash.hash(newPassword);
/*Set password of 'user'*/
}
}
有没有办法为用户实体的“密码”字段设计一个设置器,以便 UserManager 可以更改其值,但没有其他人可以做到这一点?如果不可能,是否有另一种方法可以安全地设置密码,而不会将 PasswordHash 接口暴露给客户端?请注意,CDI 不适用于 Entity 类,因此我无法将 PasswordHash 的实例直接注入其中。
【问题讨论】:
-
@BalusC 但我需要在某处定义
password,并且必须与username在同一张桌子上,因为我正在使用容器管理的安全性和表单登录。除此之外,还有其他类似情况发生的情况,如果我能在不更改实际持久数据定义的情况下解决这个问题会更好。 -
我真的不明白问题出在哪里。你不能使用
@PrePersist和@PreUpdate函数并且在实体上可能有@Transient PasswordHash hasher属性吗? -
@coladict 问题是不能从
User实体公开此行为,因为这是一个业务问题。实际的PasswordHash实现仅可通过CDI 提供给UserManager类,因为该类负责业务逻辑。如果我让UserManager成为实体侦听器,我可以使用@PrePersist和@PreUpdate,但我必须检查密码是否真的被更改了,我试图避免这种情况。
标签: jpa jakarta-ee ejb cdi