Вопрос 1 : Безопасность
Некоторые старые документы упоминание:
[...] вы выставляете предопределенныйнабор операций для клиентов, которые не находятся под вашим контролем, это почти все или ничего до сих пор.Казалось бы, нет способа раскрыть только операции чтения, полностью скрывая операции изменения состояния.
, что подразумевает, что все методы автоматически наследуются (также в соответствии со стандартным java
поведением наследования).
В соответствии с документами @ PreAuhtorize вы также можете разместить аннотацию в объявлении класса / интерфейса.
Таким образом, вы можете иметь только одно базовое расширение интерфейса JpaRepository
@NoRepositoryBean // tell Spring not create instances of this one
@PreAuthorize("hasRole('ROLE_ADMIN')") // all methods will inherit this behavior
interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> {}
, а затем получите все ваши Repository
расширения BaseRepository
.
Вопрос 2 : Безопасность
Я собираюсь бытьнемного более общий об этом.
Чтобы правильно регулировать доступ к сущностям в вашем приложении и определять что можно увидеть , вы всегда должны разделять свой проект на разные слои.
Хорошей отправной точкой будет:
layer-web
(или уровень представления): доступ к layer-business
, нет доступа к db-layer
.Может видеть DTO
модели, но не DB models
layer-business
(или бизнес-уровень): доступ к db-layer
, но нет доступа к DAO
layer-db
(или слой данных): преобразовать DTO -> DB model
.Сохраняйте объекты и предоставляйте результаты запроса
В вашем случае, я считаю, что правильнее всего было бы проверить роль в layer-business
до того, как запрос достигнет Repository
class.
@Service
public interface BookService {
@PreAuthorize("hasRole('ROLE_ADMIN')")
ActionResult saveToDatabase(final BookDTO book);
}
или, как было показано ранее
@Service
@PreAuthorize("hasRole('ROLE_ADMIN')")
public interface BookService {
ActionResult saveToDatabase(final BookDTO book);
}
Кроме того, гарантировать, что пользователь может изменять только свои собственные объекты, можно различными способами.
Spring
предоставляет все необходимые ресурсы для этого, как указывает этот ответ .
Или, если вы знакомы с AOP
, вы можете реализовать свою собственную логику.
Например (dummyCode):
@Service
public interface BookService {
// custom annotation here
@RequireUserOwnership(allowAdmin = false)
ActionResult saveToDatabase(final BookDTO book);
}
И чек:
public class EnsureUserOwnershipInterceptor implements MethodInterceptor {
@Autowired
private AuthenticationService authenticationService;
@Override
public Object invoke(Invocation invocation) throws Throwable {
// 1. get the BookDTO argument from the invocation
// 2. get the current user from the auth service
// 3. ensure the owner ID and the current user ID match
// ...
}
}
Полезные ресурсы о AOP
можно найти здесь и здесь .
Вопрос 3 : DTO
и DB models
Должен ли я вообще иметь DTO?
Да, да, вы должны.Даже если в ваших проектах всего несколько моделей и вы просто программируете для развлечения (развертывание только на локальном хосте, обучение, ...).
Чем раньше вы привыкнете разделять свои модели, тем лучшеis.
Кроме того, концептуально один представляет собой объект, поступающий из неизвестного источника, другой представляет таблицу в вашей базе данных.
Как это относится к JpaRepositories?Как использовать DTO с репозиториями Spring auto serverd rest?
Теперь в этом все дело!Вы не можете поместить DTO
в @Repository
с.Вы вынуждены конвертировать один в другой.В тот же момент вы также вынуждены проверить, что преобразование действительно.
Вы в основном гарантируете, что DTO
s (грязные данные) не коснутся базы данных, и вы устанавливаете стенусделаны из логических ограничений между базой данных и остальной частью приложения.
Также мне известно о Spring
хорошей интеграции с платформами преобразования моделей .
В чем преимущества веб-приложения multi-layer
/ modular
?
Приложения могут расти очень быстро.Особенно, когда над вами работает много разработчиков.Некоторые разработчики стремятся найти самое быстрое решение и реализовать грязные приемы или изменить модификаторы доступа, чтобы завершить работу как можно скорее.Вы должны заставить людей получать доступ к определенным ресурсам только через определенные каналы.Чем больше правил вы установили с самого начала, тем дольше будет следовать правильный шаблон программирования.Я видел, как банковское приложение стало полным беспорядком менее чем через годКогда требуется hotfix
, изменение некоторого кода приведет к двум-трем другим ошибкам .
Вы можете достичь точки, когда приложение потребляет слишком много ресурсов ОС.Если, скажем, у вас есть модуль module-batch
, содержащий фоновые задания для вашего приложения, вам будет проще извлечь его и внедрить в другое приложение.Если ваш модуль содержит логику, которая запрашивает базу данных, получает доступ к любому типу данных, предоставляет API для внешнего интерфейса, ecc ... вы будете вынуждены экспортировать весь свой код в ваше новое приложение.На этом этапе рефакторинг станет проблемой.
Представьте, что вы хотите нанять несколько экспертов по базам данных для анализа запросов, выполняемых вашим приложением.С четко определенной и разделенной логикой вы можете дать им доступ только к необходимому modules
вместо всего приложения.То же касается и внештатных фрилансеров ecc ... Я тоже пережил эту ситуацию.Компания хотела, чтобы эксперты по базам данных исправляли запросы, выполняемые приложением, но не хотела, чтобы они имели доступ ко всему коду.В конце концов, они отказались от оптимизации базы данных, потому что это могло бы открыть слишком много конфиденциальной информации извне.
И каковы преимущества разделения DTO
/ DB model
?
DTO
не коснется базы данных.Это дает вам больше защиты от атак извне - Вы можете решить, что происходит на другой стороне.Вашим
DTO
не нужно реализовывать все поля в качестве модели БД.На самом деле вы можете даже иметь карту DAO
для многих DTO
или наоборот.Существует много информации, которая не должна доходить до внешнего интерфейса, и с помощью DTO
вы можете легко это сделать. DTO
, как правило, больше, чем модели @Entity
.Принимая во внимание, что сущности отображаются (например, @OneToMany
) на другие сущности, DTO
могут просто содержать поле id сопоставленных объектов. - Вы не хотите, чтобы объекты базы данных оставались слишком длинными;и ни один не передается методами вашего приложения.Многие фреймворки фиксируют транзакции базы данных в конце каждого метода, что означает, что любое принудительное изменение, внесенное в объект базы данных, может быть зафиксировано в БД.
Лично я считаю, что любые уважительные веб-сайтыприложение должно строго разделять слои, каждый из которых несет ответственность и ограничен видимостью для других слоев.
Различие между моделями базы данных и объектами передачи данных также является хорошим примером для подражания.
В конце концов, этотолько мое мнение хотя;многие утверждают, что шаблон DTO
устарел и вызывает ненужное повторение кода, многие утверждают, что слишком большое разделение приводит к трудностям в поддержании кода.Таким образом, вы всегда должны обращаться к разным источникам, а затем применять то, что лучше для вас.
Также интересно: