Ссылка ManyToOne с зашифрованными полями дает не существует ошибки при использовании Jasypt - PullRequest
1 голос
/ 20 июля 2010

У меня проблема в следующей ситуации:

В приложении Spring, Hibernate, я получил объект пользователя и объект категории пользователя. Таблица сущности пользователя получила имя пользователя в качестве идентификатора. Это поле идентификатора не может быть зашифровано, потому что эта таблица также используется более старой программой без возможности сделать это.

Чтобы сделать ссылку ManyToOne от UserCategory на User, мне нужно поле в таблице UserCategory с уникальным именем пользователя пользователя. Я хочу зашифровать имя пользователя в таблице UserCategory с помощью Jasypt. И конечно эта работа:

    @Type(type="encryptedString") 
    @ManyToOne 
    @JoinColumn(name = "username", insertable=false, updatable=false)   
    @ForeignKey(name = "none") 
    public User getUser(){ 
            return this.user; 
    } 
    public void setUser(User user ){ 
            this.user = user; 
    } 

Но после помещения зашифрованного имени пользователя в таблицу UserCategory я не могу использовать эту запись, потому что Hibernate не может сделать ссылку на пользователя в зашифрованном поле: Вы получите следующую ошибку:

"No row with the given identifier exists: com.foo.bar.models.User#M9LgndiyCsVGqfVRVblb3A=="

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

1 Ответ

1 голос
/ 20 июля 2010

Я думаю, вы неправильно поняли, как использовать пользовательский тип пользователя, и, как я прокомментировал в моем предыдущем ответе , вы НЕ должны объявлять пользовательский тип на уровне ассоциации здесь Вы должны использовать его на уровне атрибута, то есть на атрибуте username объекта User.

Это на самом деле объясняется в документации (вставленной из Google Cache, так как сайт Jasypt в данный момент не работает):

Интеграция Jasypt с Hibernate 3

Jasypt предоставляет пакет интеграции (org.jasypt.hibernate.type) который предоставляет несколько Hibernate UserType реализации для разрешения одного или несколько свойств в сопоставленных Спящий объект, который будет объявлен зашифрованного типа . Типы разрешено хранить в зашифрованном виде включают строки, двоичные файлы (байтовые массивы), числовые типы, логические значения и даты.

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

Это может быть полезно для шифрования личные данные, личные сообщения и т. д., так, чтобы никто не доступ на чтение к «критическим» таблицам может прочитать все его содержимое.

Для шифрования в Hibernate, jasypt использует свое шифрование на основе пароля возможности и любой объект шифрования внедряя PBEStringEncryptor, PBEByteEncryptor, PBEBigIntegerEncryptor или PBEBigDecimalEncryptor может быть использован для шифровать данные, даже созданные шифровальщики пользователем.

Но шифрование устанавливает ограничение на ваше использование Hibernate : безопасность стандарты устанавливают, что два разных операции шифрования на тех же данных не должен возвращать одно и то же значение (из-за к использованию случайной соли). Потому что из этого, ни одно из полей, которые быть зашифрованным при сохранении может быть частью предложения WHERE в вашем поисковые запросы для сущности они принадлежат .

Итак, подведем итог: 1) аннотация @Type должна применяться к username и 2) вы не сможете использовать username в качестве первичного ключа (поскольку он не может быть частью объединения, как упомянуто в последнем абзаце выше).

Это означает, что вам понадобится что-то вроде этого (при условии, что вы объявили соответствующий @TypeDef):

@Entity
public class User {

    @Id @GeneratedValue
    private Long id;

    @Type(type="encryptedString") 
    private String username;

    ...
}

И соответственно изменить ассоциацию ManyToOne.

...