Reputation: 53
I have the following entity:
@Entity
public class User {
@Id
private Integer id;
private String username;
private String password;
}
To set the password, one must provide the plain-text password, but the actual password stored is a hash of the plain-text password. The problem is that the actual hash calculation is business dependent. More specifically, I have the following interface and 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'*/
}
}
Is there a way to design a setter for 'password' field of the User entity so that UserManager can change its value, but no one else can do that? If its not possible, Is there another way I can securely set the password, without exposing the PasswordHash interface to the client? Note that CDI is not available to the Entity class, so I cannot inject an instance of PasswordHash directly into it.
Upvotes: 1
Views: 225
Reputation: 7744
One way of dealing with this is not to expose the User entity directly from your service layer, only use it internally for persistence. What you usually end up doing is essentially duplicating some entities, and copying stuff back and forth. These "copied" classes are sometimes called Data Transfer Objects. There are tools like Dozer to make this easier, although arguably not prettier.
A second way is to fight Enterprise Java, and to avoid these Anemic Objects. Sooner or later though, you might have to do programmatic lookup because, as you say, the entities are not CDI-enabled. This is not pretty either, but at least you get something that is more Object-Oriented.
Upvotes: 1