Подходит ли авторизация на основе утверждений для отдельных ресурсов - PullRequest
0 голосов
/ 29 августа 2018

Я понимаю использование утверждений для вещей, которые я обычно называю «ролями» или «разрешениями». Я знаю, что утверждения являются более общими, но из того, что я видел на практике, обычно это сводится к следующему: если у пользователя есть этот набор утверждений, он может получить доступ к определенным областям или выполнять определенные функции.

Представьте себе вики-приложение. Возможно, у вас есть утверждение content_contributor , которое позволит пользователю добавлять контент, утверждение content_admin , которое позволит пользователю удалить контент, и утверждение modify_user , которое позволит предоставить права участника другому пользователю.

Если взять этот пример еще дальше, я могу ограничить пользователей, чтобы они могли видеть только контент, созданный ими или их командой.

Если пользователь может видеть только контент, созданный им самим, будем ли мы претендовать на каждую созданную им часть контента, или мы передадим это разрешение приложению?

1 Ответ

0 голосов
/ 30 августа 2018

Когда вы говорите о ролях и разрешениях , тогда вы говорите о авторизации .

Заявки обычно не для авторизация . (Идентификационные данные) Претензии для моделирования идентичности пользователя: кто является пользователем? Претензии на себя ничего не говорят об авторизации. Пользователь может претендовать на роль, но это не говорит приложению , что ему разрешено делать.

Авторизация выполняется приложением в зависимости от того, кто является пользователем. Думайте об авторизации как о наборе правил , например:

  • 18 + : разрешено, если пользователь старше 18 лет ( DateOfBirth ).

  • Использовать автомобиль : разрешить, если у пользователя есть водительские права.

Или что-то в этом роде.

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

Проблема с ролями IMO заключается в том, что они не универсальны. Я могу быть Доктором в одной больнице, в то время как я Пациент в другой. И я могу быть Admin для одного арендатора, но User для другого арендатора. Таким образом, они имеют значение только в определенном контексте.

Единственная причина для включения ролей в качестве заявки состоит в том, что вам не нужно искать эту информацию, поскольку она уже присутствует. Но, учитывая предыдущее замечание, вы на самом деле не можете включить эту информацию. И это только даст вам головную боль, когда вы делаете. Потому что вы не можете делать простые вещи, такие как обновление или изменение разрешений или настроек профиля, пока пользователь снова не войдет в систему.

Так что, как правило: держите авторизацию близко к ресурсу (api / website). Потому что это место, где реализуются бизнес-правила. И это место, где вы можете хранить и обновлять разрешения и т. Д.

Держите разделение проблем, когда дело доходит до аутентификации и авторизации. Аутентификация говорит вам, кто пользователь, а авторизация говорит вам, что ему разрешено делать. Не смешивайте эти два.


Перевод этого в ваше вики-приложение:

Создайте отдельный контекст, в котором вы храните информацию авторизации, такую ​​как роли и разрешения. Вы можете управлять этим в центральном ресурсе (для нескольких приложений) или использовать контекст в вашем приложении. Я бы не стал смешивать этот контекст с бизнес-контекстом .

Добавить пользователя в контексте авторизации и добавить роль content_contributor . В приложении прочитайте разрешения (из центрального API, локального контекста авторизации, файла настроек или чего-либо, что подходит лучше всего) для этого пользователя (на основе утверждения sub ). Кэшируйте его, чтобы повысить производительность, и применяйте правила, чтобы определить, разрешен ли пользователю доступ к ресурсу.

Вы можете расширить это с помощью авторизации на основе ресурсов . Сохраните значение заявки sub в записи содержимого, чтобы определить владельца. Если текущий пользователь соответствует значению претензии sub , то текущий пользователь является владельцем.

Вы можете использовать тот же подход для команд. Добавьте таблицу groups в бизнес-контекст и свяжите пользователя с одной или несколькими командами. Непосредственно используя значение претензии sub или косвенно, используя таблицу Users, также в бизнес-контексте, где пользователь связан со значением претензии sub . Вы можете добавить имя и т. Д., Если хотите показать эту информацию (как в отчете).

Вы можете сохранить идентификатор команды и / или идентификатор пользователя или sub значение претензии (владелец является членом той же команды, что и текущий пользователь) в контенте запись для определения разрешенного доступа для пользователя.


Моя настройка будет такой:

Контекст идентификации : пользователи + пользовательские требования. Только для аутентификации. Приложение не зависит.

Контекст авторизации : пользователи (id = подпретензия) + для приложения: роли, разрешения и т. Д. В отдельных «локальных» базах данных или в центральной базе данных. Только для авторизации.

Бизнес-контекст : пользователи (Id, Name, вложенная заявка «внешний ключ», без фактической связи с базой данных, поскольку таблица находится вне контекста) + команды, профиль, настройки и т. Д. Связаны с sub значение претензии, когда таблица пользователей пропущена.

Чтобы поддерживать актуальность таблицы пользователей в бизнес-контексте, периодически обновляйте значения. Например, вы можете обновить значения, когда пользователь входит в систему через x раз. Или время от времени запрашивайте Identity Context (используя API) для запроса информации о пользователе (используя конечную точку User Info для идентификации).

Во всех контекстах может быть таблица users , но все они имеют различное значение и содержат другую информацию. Таким образом, нет избыточной информации.

Авторизация происходит внутри приложения и основана на бизнес-правилах (политиках) и информации авторизации из контекста авторизации.

В качестве последнего замечания, когда текущей системе требуются утверждения о ролях (например, для User.IsInRole() или [Authorize("role")]), вы можете прочитать (из кэша) роль / разрешения для каждого вызова и добавить их в коллекцию утверждений текущий пользователь (преобразование претензий).

...