Выполните проверку один раз во время строительства и выбросьте (или верните NULL с завода), если условие безопасности не выполнено.После этого наличие ссылки на данный объект модели является достаточным доказательством того, что вы прошли проверку безопасности в какой-то более ранний момент.Если вы обеспокоены тем, что это может вызвать проблемы TOCTTOU , убедитесь, что эти объекты станут непригодными для использования в конце определенной приложением концепции «игровой ход» (обычно транзакция базы данных);в любом случае, это хорошая практика.
Такой подход к безопасности называется дисциплина способностей .Думайте о своих объектах как о коробках, которые имеют некоторую власть внутри них (в их частных переменных).Нажав кнопки на блоке, вы можете использовать только настраиваемую долю этих полномочий только так, как это позволяет программист объекта.
Например, например, вы пишете приложение календаря сSQL-бэкэнд.Существует объект SQLTransaction
, который не переживает транзакцию (как указано выше), но все же обладает всеми правами на все таблицы, используемые приложением.Это большая сила, которую вы не хотите передавать пользователям вашего API (явно или по ошибке, подумайте о внедрении SQL).Вместо этого вы раздаете User
объекты, которые моделируют полномочия на запись только в строку этого пользователя в таблице Users;также User
может создавать, читать, обновлять, удалять Appointment
объекты, которые аналогичным образом представляют ограниченные полномочия в таблице назначений.
Чтобы поддерживать RBAC во всем вашем API, вы должны убедиться в соблюдении следующих условий:
- Только законные пользователи могут получить доступ к объекту
User
, который их представляет.Здесь вы подключаете систему аутентификации к конструктору User
; - Объекты
User
не не пропускают права доступа , т. Е. Вы должны проверить свой API, чтобы убедиться, чтоосуществляя вызовы методов для User
(или любого связанного объекта, который они возвращают, рекурсивно), вы не можете прочитать или изменить любые ресурсы, которые не принадлежат этому пользователю.Здесь вы можете применить шаблон facet - например, User.GetAppointments()
возвращает реальные Appointment
экземпляры для встреч, созданных этим пользователем, но оболочки только для чтения для тех, которые созданы кем-то еще.