Контрольный вопрос:как защитить коллекции Hibernate, возвращающиеся с клиента на сервер?
-
23-09-2019 - |
Вопрос
У меня есть простой pojo с именем «Родитель», который содержит коллекцию объектов «Дочерний».
В hibernate/jpa это просто ассоциация «один ко многим», дети не знают своего родителя:эти дочерние объекты могут иметь разные типы родительских объектов, поэтому их легче не знать (подумайте о дочернем объекте, который представляет теги, а родители могут быть объектами разных типов, имеющими теги).
Теперь я отправляю свой родительский объект в клиентское представление моего веб-сайта, чтобы пользователь мог его изменить.
Для этого я использую Hibernate/GWT/Gilead.
Мой пользователь вносит некоторые изменения и нажимает кнопку «Сохранить» (ajax), которая отправляет мой родительский объект на сервер.поля моего родителя были изменены, но, что более важно, некоторые дочерние объекты были добавлены или удалены в коллекции.
Подводя итог, когда родительский объект возвращается на сервер, он теперь имеет в своей коллекции:- Новые объекты «детского», где идентификатор нулевой и должен быть настойчивым - модифицированные «детские» объекты, где идентификатор не является нулевым и должен быть слияние - потенциально взломанные «детские» объекты, где идентификатор не является нулевым, но изначально не принадлежит Родитель - детские объекты отсутствуют (удалены):нужно удалить
Как сохранить родительский объект (и его коллекцию)?Вы загружаете родительскую коллекцию из базы данных, чтобы сравнить каждый объект измененной коллекции и убедиться, что нет взломанного элемента?Очищаете ли вы старую коллекцию (чтобы удалить потерянную коллекцию) и заново добавляете новый дочерний элемент (но есть какой-то дочерний элемент, который не был изменен)?
Спасибо
ПС:извините за мой английский, надеюсь, вы поняли концепцию;)
Решение 2
Лучшее решение, которое я нашел, — это управлять DTO, созданным вручную.DTO отправляет клиенту только необходимые данные.Для каждого поля, которое я хочу установить в режиме ReadOnly, я вычисляю подпись на основе секретного ключа, который отправляю клиенту с помощью моего dto.
Когда мой DTO возвращается на сервер, я проверяю подпись, чтобы убедиться, что мои поля только для чтения не изменились (пересчитываем подпись с возвращающимися полями и сравниваем ее с подписью, возвращающейся с помощью dto)
Это позволяет мне указывать поля только для чтения и быть уверенным, что мои объекты не будут взломаны.
Другие советы
Что-то в вашем наборе должно обеспечивать логику, о которой вы говорите, и, учитывая ваши обстоятельства, вероятно, это вы.Вам нужно будет получить текущее постоянное состояние объекта, прочитав его из источника данных, чтобы вы могли выполнить сравнение.Имейте в виду, что если несколько законных действий могут одновременно обновить ваш родительский объект и его коллекцию, вам придется очень внимательно определить зернистость транзакции и потокобезопасную природу вашего кода.
В любом случае, это непростая проблема, и вполне могут быть функции платформы, которые могут помочь, но мне еще предстоит найти что-то, что решило бы эту проблему для любой реальной реализации, с которой я столкнулся, особенно там, где у меня есть логика, которая пыталась различать законные и «взломанные» данные.
Вы можете рассмотреть возможность изменения вашей архитектуры таким образом, чтобы родительский и дочерний элементы сохранялись в отдельных действиях.Это может быть неуместно в вашем случае, но вы можете получить более тонкую структуру транзакций, разделив действия сохранения и обеспечив безопасность, ориентированную на детей, что сделает вашу проблему взлома немного более управляемой.
Удачи.Я рекомендую вам нарисовать подробную блок-схему вашей логики, прежде чем писать слишком много кода.