Должны ли пользовательские проверки прав доступа выполняться в модели или контроллере? И кто должен обрабатывать проверки разрешений, объект User или какой-либо помощник UserManagement?
Где это должно произойти?
Проверка в контроллере:
class MyController {
void performSomeAction() {
if (user.hasRightPermissions()) {
model.someAction();
}
}
...
Наличие проверок в контроллере помогает сделать модели простыми действиями, поэтому мы можем сохранить всю логику для контроллеров.
Проверка в модели:
class MyModel {
void someAction() {
if (user.hasRightPermissions()) {
...
}
}
...
Помещая проверки в Модель, мы усложняем Модель, но также и не допускаем, чтобы мы случайно не позволяли пользователям делать то, что они не должны делать в Контроллере.
И кем?
Как только мы остановимся на месте, кто должен делать проверки? Пользователь?
Class User {
bool hasPermissions(int permissionMask) {
...
}
...
Но на самом деле не ответственность пользователя знать, что он или она может получить, так что, может быть, какой-нибудь класс помощника?
Class UserManagement {
bool hasPermissions(User user, int permissionMask) {
...
}
...
Я знаю, что обычно задают только один вопрос, ну, в общем, вопрос, но я думаю, что на них можно хорошо ответить вместе.
источник
Безопасность - это междисциплинарная проблема, поэтому ее необходимо реализовать на нескольких уровнях. Ниже приведен пример для MVC, но концепция применима к другим архитектурам и / или шаблонам, вам просто нужно определить точки исполнения.
Где это должно произойти?
Представления могут содержать элементы пользовательского интерфейса (виджеты, кнопки, меню и т. Д.), Которые должны отображаться или не отображаться для некоторых пользователей в зависимости от их разрешений. Это может быть обязанностью механизма представления , так как вы не хотите, чтобы каждое представление обрабатывало это самостоятельно. В зависимости от типа элементов, которые вы делаете, вы должны перевести эту ответственность в другое место. Например, представьте себе меню, в котором некоторые элементы должны отображаться, а некоторые нет. Элементы могут быть реализованы в виде списка где-нибудь и фильтровать этот список на основе разрешений, а затем перенаправить его в представление.
Контроллеры отвечают на запросы, поэтому, если у пользователя нет разрешения на выполнение действия, его следует проверить перед тем, как оно будет вызвано, перенося ответственность на вызывающего действие, а не оставляя его в контроллере. Это дает преимущество в поддержании чистоты вашего контроллера, и если что-то меняется в разрешениях, вам не нужно просеивать свои контроллеры, чтобы применить эти изменения.
Ресурсы отображаются на основе разрешений. Обычно это делается на уровне базы данных , поскольку вы не хотите извлекать все из базы данных и затем применять разрешения.
Как видите, в зависимости от того, что вы хотите авторизовать, есть разные места, где это нужно сделать. Цель состоит в том, чтобы быть как можно более ненавязчивым, чтобы при изменении политики безопасности ее можно было легко применять, желательно без изменения кода вашего приложения. Это может быть недопустимо для небольших приложений, где набор разрешений довольно мал и меняется не очень часто. В корпоративных приложениях история совсем иная.
Кто должен это делать?
Очевидно, не модель. Каждый уровень должен иметь точку принудительного исполнения, которая обрабатывает авторизацию. Текст, выделенный курсивом выше, выделяет возможные точки исполнения для каждого уровня.
Посмотрите на XACML . Вам не нужно реализовывать его как есть, но он даст вам некоторые указания, которым вы могли бы следовать.
источник
Я использую следующую схему. Стоит сказать, что большинство проверок полномочий пользователей можно разделить на два общих случая:
Доступ к действиям контроллера без проверки атрибутов обычно реализуется в средах MVC. Это просто: вы определяете правила, у ваших пользователей есть роль. Вы просто проверяете, что у пользователя есть разрешение на поиск действий в правилах.
Доступ пользователя к конкретной модели должен быть определен в модели. (Актер - это базовый класс пользователя. Предположим, это может быть клиент, продавец или гость.)
Размещение этой логики в модели приносит некоторую прибыль. Метод проверки доступа может быть унаследован, вам не нужно создавать никаких дополнительных классов, вы можете использовать общие преимущества ООП.
Далее, чтобы упростить проверку доступа, мы берем некоторые предположения, которые почти всегда реализуются уже для простоты и хорошего стиля:
С этими допущениями действия, которые используют идентификатор модели, могут быть связаны с конкретным экземпляром модели. Фактически, большинство действий могут быть легко преобразованы и перемещены, чтобы соответствовать предположениям, изложенным выше.
Затем некоторый базовый абстрактный класс контроллера должен быть определен и унаследован.
Вы можете вызвать метод SomeController :: checkModelAccess ($ id), когда создаете свои меню и решаете, показывать ли какую-либо ссылку.
источник
И в модели, и в представлении
В представлении - потому что пользовательский интерфейс не должен отображать элементы пользовательского интерфейса, доступные только текущему пользователю.
(как, скажем, кнопка «Удалить» должна быть показана людям с соответствующими разрешениями)
В модели - потому что ваше приложение, вероятно, имеет какой-то API, верно? API также должен проверять разрешения и, возможно, повторно использовать модель.
(как, скажем, у вас есть кнопка «Удалить» в пользовательском интерфейсе и метод «http: / server / API / DeleteEntry / 123» API одновременно)
источник
MVC - это шаблон презентации. Как таковой, у контролера должны быть только обязанности относительно представления. Некоторые разрешения применяются к презентации, такие как режим эксперта, экспериментальные функции пользовательского интерфейса или различные конструкции. Они могут быть обработаны MVC-контроллером.
Многие другие виды разрешений относятся к нескольким слоям приложения. Например, если вы хотите, чтобы пользователи могли только просматривать данные и ничего не менять:
В этом подходе есть некоторое дублирование. Но так как презентация обычно изменчива, можно найти хороший повод для проверки разрешения в обычно более стабильной части приложения, даже если это означает некоторые избыточные проверки в случае, если уровень презентации работает как задумано.
источник