2013-08-14 2 views
2

У меня есть ситуация, использующая сохранение спящего режима с помощью спящего режима и хотя я думал о нескольких подходах к хакерству, я не знаю, как лучше всего решить эту проблему, используя спящий режим настойчивость и валидацию.Правильный способ использования спящего режима сдерживания и валидации вместе

Проще говоря, у меня есть объект User, и я хочу его сохранить. Но прежде, чем я его сохраню, я хочу проверить его. Довольно стандартный материал.

Теперь объект пользователя имеет пароль, и у нас есть правила относительно действительных паролей. Например: минимум 8 символов, включите хотя бы 1 номер и т. Д. Я хочу проверить эти вещи.

Но когда я настаиваю, мне нужно зашифровать/солить/хешировать пароль. Но после того, как я сделаю соление/хэширование, очевидно, что нет разумного способа выполнить вышеуказанные проверки пароля.

Итак, я думал, что могу использовать аннотации @PrePersist и @PreUpdate для этого. Моя мысль была в классе User. У меня есть метод, называемый onCreate(). Я помечать его с @PrePersist и я сделать что-то вроде этого (у меня есть что-то подобное для OnUpdate()):

@PrePersist 
protected void onCreate() { 
    encryptPassword(); 
} 

Я подумал, что, когда я называю entityManager.persist() было бы назвать первым валидаций, а затем вызвать onCreate() и затем сохраняться. Таким образом, проверки подтвердят исходный, несолистый/хешированный пароль. И соление/хеширование произойдет позже.

Когда я запускал свои тесты и отлаживал, я обнаружил, что методы, помеченные с помощью @PrePersist, вызываются до запуска проверки, что означает, что я больше не могу проверять свой пароль.

Как правильно заманить/хешировать пароль в жизненном цикле entityManager.persist(), чтобы я мог правильно проверить и после этого соль и хэш и, наконец, сохраниться?

Спасибо.

ответ

1

Используйте два свойства bean, один для сохранения, а другой для проверки/преобразования. Что-то вроде этого:

@Entity 
@MyCustomConstraint(...) 
public class User implements Serializable { 

    // place persistence annotations here, for example 
    @Lob @Column(...) 
    private byte[] hashedPassword; 
    // place validation constraints here, for example 
    @Size(min = 8, max = 16) 
    @Transient 
    private String password; 

    public byte[] getHashedPassword() { 
     return this.hashedPassword; 
    } 

    protected void setHashedPassword(byte[] hashedPassword) { 
     this.hashedPassword = hashedPassword; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
     this.setHashedPassword(this.hashAndSaltMyPassword(this.password)); 
    } 

    protected String getPassword() { 
     return this.password; 
    } 

    protected byte[] hashAndSaltMyPassword(String password) { 
     ... 
    } 
} 

Выполнено.

+0

Спасибо, это имеет смысл, но ограничивает мою способность проверять пароль. У меня есть собственный валидатор паролей, который я установил на уровне класса. Это уровень класса, потому что я должен выполнить проверку кросс-поля. В частности, мне нужно проверить пароль, это не то же самое, что и имя пользователя. Из-за этого я считаю, что мне нужно иметь поле пароля @Transient, которое хранит пароль открытого текста для проверки в моем настраиваемом валидаторе. Если бы я мог просто использовать простые аннотации на уровне поля, ваше предложение будет работать нормально. Любые мысли о том, как добиться того, что вы описали с аннотацией проверки уровня на уровне? – lostdorje

+0

Ну, вы уже описали свой ответ, но я все равно отредактировал ответ. Чтобы суммировать, сохраните пароль открытого текста в поле '@ Transient', добавьте ограничение уровня класса и напишите защищенный getter. Я бы предложил определить ваш валидатор в том же пакете. – rdcrng

+0

Правильно, спасибо за это. Мне удалось сделать это без необходимости защищенной версии getPassword(). Если plaintext pwd не имеет значения null, возвращайте plaintext pwd (он будет равен нулю только при создании нового пользователя или изменении pwd). Если plaintext pwd равно null, верните хешированную версию. И да, я подумал о том, чтобы положить валидаторы в один и тот же пакет, но надеялся не загрязнять пространство пакета сущности, но все больше и больше кажется, что это может быть правильным, если учесть жесткую связь объектов и их валидаторов. – lostdorje

Смежные вопросы