Здравствуйте, dak565656, Вы писали:
D>Есть типичное трехзвенное приложение в духе Domain Model. Т.е. имеем БД, слой доступа к БД (ORM), application layer и presentation layer в виде смарт-клиента, богатого на сложные м красочные контролы.
D>Для каждого объекта в системе хотелось бы определить права доступа: т.е. есть много юзеров, каждый из которых может или не может читать/изменять/создавать/удалять объекты. Т.е. определяется набор действий (создание, удаление, чтение итд), набор объектов, над которыми могут производиться эти действия (счет, организация, персона итд итп), а также возможно наличие ролей (т.е. определенный набор действий над определенными объектами).
D>Вопрос: как лучше всего это реализовать? Если подходить в лоб, то сталкиваемся с проблемой кросскаттинга — весь программный код (а особенно на клиенте) будет пропитан кодом определения доступа.
D>Наверняка есть какие-то best practices или даже небольшие фреймворки, свзязанные с этой проблемой
Посоветуйте что-нибудь
Всё написаное дальше из моего опыта испльзования spring security.
В presentation layer кода определения доступа быть не должно, единственное что там будет, это включение/выключение элементов управления, которые отвечают за функции приложения, которые доступны/недоступны текущему пользователю. Собственно проверки начинаются на интерфейсах между presentation и слоем сервисов (бизнес логикой).
С spring security встроенные проверки приблизительно такого типа (естественно можно расширять своими) :
1. аутентифицированый пользователь имеет право вызывать метод интерфейса
2. у аутентифицированого пользователя есть права на доступ к объекту переданому в качестве параметра
Сами проверки реализованы через AOP.
При этом есть некое дублирование проверок, т.е. с одной стороны сам presentation не даёт возможности сделать запрещённую операцию пользователю, с другой стороны, если злоумышленик попробует вручную послать запрещённую команду, которая не нарушает протокол взаимодействия presentation и service слоёв, но недоступна текущему пользователю — то это отловит прослойка безопасности вокруг service layer-а.
Кроме этого между слоями service и dao, опять же с помощью AOP реализована фильтрация domain объектов в коллекциях, т.е. абсолютно не вмешиваясь в работу этих слоёв возвращаемые коллекии фильтруются по ACL (access control list). Тут я вижу однако минусы для масштабирования, а именно, фильтрация происходит на во время запроса в БД, а после него. Более предпочтительным выглядит вариант, когда не менее прозрачно (с помощью механизмов расширения ORM фреймворка, в hibernate это можно сделать фильтром) фильтрация делается во время запроса. В тех проектах, что я делал необходимости єто делать не было, т.к. не было такого количества данных, которые бы приводили к проблемам в данном месте, но при увеличении количества данных, проблемы будут
Я бы сделал такой вывод, что если приложение разложено по слоям, то добавить проверку доступа с помощью AOP можно довольно малыми усилиями, а в идеале абсолютно прозрачно