Стандартні практики контролю доступу (модель дизайну)


9

Я дивлюся на свій дизайн інтерфейсу, і я намагаюся вирішити, який є найбільш "правильним" способом здійснення управління доступом на основі ролі, з огляду на userта, subjectякі userхотіли б отримати.


Наскільки я бачу, у мене є три основні варіанти (четвертий - бастардизація першої трійки, а п'ятий - твіст четвертого):

  1. Запитуйте subjectсписок із дозволами, які userмає -subject.allowAccess(user.getPermissionSet)
  2. Запитайте userсписок із необхідними дозволами subject-user.hasPermissionTo(subject.getRequiredPermissions())
  3. Запросити сторонню особу, щоб знайти перехрестя дозволів - accessController.doPermissionSetsIntersect(subject.permissionSet, user.getPermissionSet())
  4. Запитуйте або subject/ user, при цьому делегуючи "рішення" сторонньому класу
  5. Мати userспробу доступу до subjectі видасть помилку , якщо доступ не дозволений

Я схиляюся до варіанту чотири - Попросити subjectмістити accessControllerполе, де викликає subject.userMayAccess(User user)делегувати операцію a la:

class Subject {
    public function display(user) {
        if(!accessController.doPermissionSetsIntersect(this.permissionSet, user.getPermissionSet())) {
            display403(); //Or other.. eg, throw an error..
        }
    }
}

.. але тоді виникають додаткові питання:

  • має accessControllerбути полем проти статичного класу ..?
  • Чи повинен subject знати, які дозволи потрібно переглядати?
  • де тут грає принцип найменшого знання стосовно покликання subject.display()? Чи повинні абоненти subject.display()коли-небудь знати, що діє контроль доступу? (де subject.display()є остаточний "шаблонний метод")
  • мати subject.display()керування доступом, кидаючи виняток, коли користувач не має необхідного дозволу?

Що б вважалося "найкращою практикою" у цій ситуації? Де насправді повинна виникнути відповідальність за здійснення перевірок?

Оскільки це дещо як академічна вправа, яка згодом прогресує у впровадженні, посилання на моделі дизайну були б вдячні.

Відповіді:


7

Найкраща практика - використовувати щось, відоме як модель перехоплення, для перехоплення дзвінків у захищені зони.

Цього можна досягти, використовуючи АОП або перехресні проблеми, застосовані до точок входу.

Суб'єкт ніколи не повинен знати про те, хто здатний його переглянути. Це надмірно ускладнює предметний код і немає підстав для його необхідності, якщо ви ненавмисно не надаєте механізм прямого доступу до тієї ж функції.

Переважно, що абонент і абонент не повинні знати про доступ, крім обробки відхилень. Однак проблема буде залежати від системи, яку ви впроваджуєте, і від того, як ви отримаєте доступ до облікових даних / довірителя безпеки для абонента. Наприклад, в системах SOAP ця інформація додається до заголовка повідомлення SOAP, тоді як у системі Windows вона буде доступна через механізм аутентифікації Windows.

Якщо ви використовуєте схему підходу AOP або схеми перехоплення, вона б викинула будь-які необхідні винятки, і клієнт (абонент) повинен вирішувати будь-які кинуті винятки.

Таким чином ви зберігаєте окремий код свого клієнта, послуги та автентифікацію, не перетинаючи знання чи функціональні можливості.



2

Я думаю, що ваш варіант 3 є найближчим, але замість того, щоб допитувати userта subjectпро їх набори дозволів, вам слід передати userта subjectдо контролера доступу.

class Subject {
    public function display(user) {
        if(!accessController.checkAccess(this, user, AccessControl.Read)) {
            display403(); //Or other.. eg, throw an error..
        }
    }
}

Контролер доступу повинен відповідати як за отримання наборів дозволів, так і за перевірку, чи достатній доступ. Таким чином ви виділите як логіку зберігання, так і логіку перевірки у контролері доступу, окремо від користувача та предмета.

Інший елемент, можливо, відсутній у вашому прикладі - це те, яку операцію виконують. Деякі користувачі можуть мати право читати деякі дані , але не оновлювати, видаляти, виконувати і т.д. Таким чином , ви можете мати checkAccessметод на контролер доступу з трьома параметрами: user, subject, operation. Ви також можете надати додаткову інформацію назад, checkAccessщоб повернути інформацію про те, чому доступ не був наданий.

Наприклад, делегування всього цього контролеру доступу пізніше дозволяє замінити те, як представлені ваші дозволи. Ви можете почати з керування доступом на основі ролей і пізніше перейти до претензій. Ви можете зберігати дозволи в простій структурі для початку та пізніше додавати ієрархічні групи / ролі та дозволені операції з різними типами предметів. Якщо не вводити набори дозволів в інтерфейс, це допоможе ввімкнути це.

Якщо ви використовуєте AOP або якийсь код котла для підключення цього, на мою думку, менш важливий.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.