Есть типичное трехзвенное приложение в духе Domain Model. Т.е. имеем БД, слой доступа к БД (ORM), application layer и presentation layer в виде смарт-клиента, богатого на сложные м красочные контролы.
Для каждого объекта в системе хотелось бы определить права доступа: т.е. есть много юзеров, каждый из которых может или не может читать/изменять/создавать/удалять объекты. Т.е. определяется набор действий (создание, удаление, чтение итд), набор объектов, над которыми могут производиться эти действия (счет, организация, персона итд итп), а также возможно наличие ролей (т.е. определенный набор действий над определенными объектами).
Вопрос: как лучше всего это реализовать? Если подходить в лоб, то сталкиваемся с проблемой кросскаттинга — весь программный код (а особенно на клиенте) будет пропитан кодом определения доступа.
Наверняка есть какие-то best practices или даже небольшие фреймворки, свзязанные с этой проблемой Посоветуйте что-нибудь
Здравствуйте, 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 можно довольно малыми усилиями, а в идеале абсолютно прозрачно
Здравствуйте, dak565656, Вы писали:
D>Есть типичное трехзвенное приложение в духе Domain Model. Т.е. имеем БД, слой доступа к БД (ORM), application layer и presentation layer в виде смарт-клиента, богатого на сложные м красочные контролы. D>Для каждого объекта в системе хотелось бы определить права доступа: т.е. есть много юзеров, каждый из которых может или не может читать/изменять/создавать/удалять объекты. Т.е. определяется набор действий (создание, удаление, чтение итд), набор объектов, над которыми могут производиться эти действия (счет, организация, персона итд итп), а также возможно наличие ролей (т.е. определенный набор действий над определенными объектами). D>Вопрос: как лучше всего это реализовать? Если подходить в лоб, то сталкиваемся с проблемой кросскаттинга — весь программный код (а особенно на клиенте) будет пропитан кодом определения доступа. D>Наверняка есть какие-то best practices или даже небольшие фреймворки, свзязанные с этой проблемой Посоветуйте что-нибудь
Все написаное дальше из моего опыта работы с spring security.
В слое представления нет проверок доступа к конкретным объектам, есть проверки показывать/скрывать элементы управления, которые дают возможность воспользоваться функцией доступной/закрытой для текущего пользователя.
На границе между слоями представления и служб, есть прослойка, которая реализована с помощью AOP, которая проверяет доступ пользователя к конкретной функции в интерфейсе между представлением и службами. Также она может проверять и доступ к объекту переданому в качестве параметра. Это то, что есть из коробки, можно добавить свои проверки. Естественно это не требует изменения ни presentation, ни service слоя (конфигурация делается через IoC контейнер).
Ясно что есть некое дублирование проверок, но оно, думаю, оправдано. С одной стороны представление не даёт делать запрещёного, с другой слой сервисов проверяет всё сам. Это для случая если у нас поменяется клиент или злоумышленик подделает запрос к слою сервисов вручную.
На границе между слоем служб и слоем DAO, также есть AOP прослойка, одна из основных задачи которой фильтрация коллекций на основе прав доступа текущего пользователя. Ясно тут есть проблема с масштабируемостью, т.к. фильтрация проводиться после вычитки из БД. Я лично не сталкивался с проблемой производительностив по этой причине, но предполагаю, что она реальна при большом объеме данных. Если бы она возникла, то я бы её решал используя механизмы расширения ORM (в моём случае фильтры hibernate), чтоб фильтрация прав доступа производилась во время вычитки из БД.
Вывод я делаю такой: при правильном разложении на слои можно малыми усилиями добавить проверку доступа.
Re[2]: Права доступа к объектам приложения
От:
Аноним
Дата:
29.08.08 04:44
Оценка:
KRA>В presentation layer кода определения доступа быть не должно, единственное что там будет, это включение/выключение элементов управления, которые отвечают за функции приложения, которые доступны/недоступны текущему пользователю.
Как это реализуется? Делается запрос на application слой типа: if(AppLayer.CanWrite(user)) then .... if (AppLayer.CanRead(user)) .... then итд...?
KRA>spring security
К сожалению есть только на яве Я же использую дотнет
KRA>добавить проверку доступа с помощью AOP можно довольно малыми усилиями, а в идеале абсолютно прозрачно
Т.е. предлагаете использовать AOP? Т.е. Каждый раз когда клиент что-то запрашивает, он передает свои данные, на основании которых логика аспекта фильтрует коллекции?
Re[3]: Права доступа к объектам приложения
От:
Аноним
Дата:
29.08.08 05:51
Оценка:
Здравствуйте, Аноним, Вы писали:
KRA>>В presentation layer кода определения доступа быть не должно, единственное что там будет, это включение/выключение элементов управления, которые отвечают за функции приложения, которые доступны/недоступны текущему пользователю. А>Как это реализуется? Делается запрос на application слой типа: if(AppLayer.CanWrite(user)) then .... if (AppLayer.CanRead(user)) .... then итд...?
Почти, проверка делается на основании роли . Т.е. if(AppLayer.HasRole(ADMIN)) then... . Про идентификацию пользователей см. ниже.
KRA>>spring security А>К сожалению есть только на яве Я же использую дотнет
Возможно, есть что-то подобное для .нет.
KRA>>добавить проверку доступа с помощью AOP можно довольно малыми усилиями, а в идеале абсолютно прозрачно А>Т.е. предлагаете использовать AOP? Т.е. Каждый раз когда клиент что-то запрашивает, он передает свои данные, на основании которых логика аспекта фильтрует коллекции?
Каждый раз передавать данные пользователя не нужно. Более предпочтительный вариант это механизм сессии (сеанса связи), т.е. клиент один раз при создании сессии передаёт данные, а дальше запросы от него приходят в контексте сессии. Реализация сессий зависит то транспорта. В http для этого чаще всего используются куки. При использовании сокетов с постоянно установленным соединением, идентификатором сеанса может быть сам сокет.
Re[4]: Права доступа к объектам приложения
От:
Аноним
Дата:
29.08.08 08:24
Оценка:
А>Каждый раз передавать данные пользователя не нужно. Более предпочтительный вариант это механизм сессии (сеанса связи), т.е. клиент один раз при создании сессии передаёт данные, а дальше запросы от него приходят в контексте сессии. Реализация сессий зависит то транспорта. В http для этого чаще всего используются куки. При использовании сокетов с постоянно установленным соединением, идентификатором сеанса может быть сам сокет.
Ну т.е. по сути мы вместо своей информации о пользователе передаем связанную с ней информацию неявно... Проблема в том, что, во-первых, я не знаю наперед какой у меня будет транспорт, а во-вторых транспорт может не поддерживать сессии
А>Возможно, есть что-то подобное для .нет.
не нашел
А>Почти, проверка делается на основании роли . Т.е. if(AppLayer.HasRole(ADMIN)) then... . Про идентификацию пользователей см. ниже.
Дело в том, что возможны более комплексные проверки: например юзер может быть с такой-то ролью, но дополнительно к роли иметь более мелкие права — например роль не предусматривает добавление объектов типа А, при этом я могу дополнительно дать право на это.
Да и в любом случае — получается кросскаттинг на клиенте: куча проверок (сплошные if'ы) в самых разных местах (чем богаче визуальный контрол, тем больше проверок) ....
Здравствуйте, Аноним, Вы писали:
А>Ну т.е. по сути мы вместо своей информации о пользователе передаем связанную с ней информацию неявно... Проблема в том, что, во-первых, я не знаю наперед какой у меня будет транспорт, а во-вторых транспорт может не поддерживать сессии
Думаю, надо смотреть по месту.
А>>Возможно, есть что-то подобное для .нет. А>не нашел Смотрю, что в .NET Framework 3.5 подобные механизмы встроены.
А>>Почти, проверка делается на основании роли . Т.е. if(AppLayer.HasRole(ADMIN)) then... . Про идентификацию пользователей см. ниже. А>Дело в том, что возможны более комплексные проверки: например юзер может быть с такой-то ролью, но дополнительно к роли иметь более мелкие права — например роль не предусматривает добавление объектов типа А, при этом я могу дополнительно дать право на это. А>Да и в любом случае — получается кросскаттинг на клиенте: куча проверок (сплошные if'ы) в самых разных местах (чем богаче визуальный контрол, тем больше проверок) ....
Я написал не совсем точно. В spring security используется понятие GrantedAuthority (обычно совпадает с ролью, отсюда и пример выше), что по смыслу значит "доступ делать такое-то действие", т.е. пользователю или группе даётся доступ и проверяется не роль, а именно доступ на действие. if(AppLayer.isGranted(CREATE_ORDER)) then ...