Каков наилучший способ управления разрешениями для веб-приложения - битовая маска или таблица базы данных? - PullRequest
49 голосов
/ 14 октября 2008

Я рассматриваю лучший способ разработки системы разрешений для веб-приложения с правами администратора. В приложении может быть много пользователей, каждому из которых может быть назначена определенная роль; некоторым из этих пользователей может быть разрешено выполнять определенные задачи вне роли.

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

User ID          Manage Users     Manage Products     Manage Promotions     Manage Orders
1                true             true                true                  true
2                false            true                true                  true
3                false            false               false                 true

Еще один способ, о котором я подумал, - использовать битовую маску для хранения этих пользовательских разрешений. Это ограничит число задач, которыми можно управлять, до 31 для 32-разрядного целого числа со знаком, но на практике у нас вряд ли будет более 31 конкретной задачи, которую может выполнить пользователь. Таким образом, схема базы данных будет проще, и нам не придется менять структуру таблицы каждый раз, когда мы добавляем новую задачу, которая требует контроля доступа. Как это:

User ID          Permissions (8-bit mask), would be ints in table
1                00001111
2                00000111
3                00000001

Какие механизмы обычно используют здесь люди и почему?

Спасибо!

Ответы [ 8 ]

72 голосов
/ 14 октября 2008

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

Хотя это может показаться более громоздким, иметь таблицу возможных разрешений, таблицу пользователей и таблицу ссылок между ними - лучший и самый понятный способ организовать это. Это также значительно упрощает ваши запросы и обслуживание (особенно для новичка).

31 голосов
/ 14 октября 2008

как насчет создания таблицы разрешений, а затем таблицы UserPermission для хранения отношений?

Вам больше никогда не придется изменять структуру, и вы можете добавить столько разрешений, сколько пожелаете.

22 голосов
/ 14 октября 2008

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

UserID | Permission
===================
1      | 1              1 representing manage users
1      | 2              2 being manger products
2      | 3 

Этот способ будет проще поддерживать и добавить позже.

Я бы также использовал отдельную таблицу для управления разрешениями.

PermissionID | Description
==========================
1            | Manage Users
2            | Manager Products
7 голосов
/ 14 октября 2008

Обычно у меня есть таблица Users, таблица Roles и таблица UserRoles. Таким образом, вы можете иметь неограниченное количество ролей, не меняя структуру БД, и пользователи могут быть в нескольких ролях.

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

Структура выглядит так:

create table Users (
 id int identity not null,
 loginId varchar(30) not null,
 firstName varchar(50) not null,
 etc...
)

create table Roles (
 id int not null,
 name varchar(50) not null
)

create table UserRoles (
 userId int not null,
 roleId int not null
)
3 голосов
/ 14 октября 2008

Я бы предложил абстрагировать разрешения вашего веб-приложения с помощью концепции поставщика ролей. Начиная с версии 2.0, это предоставляется для .NET как System.Web.Security.RoleProvider .

Основная идея заключается в том, что вы используете существующую инфраструктуру, выписывая свои проверки разрешений на основе инфраструктуры, а не на конкретный механизм хранения. Затем вы можете подключить любой доступный механизм хранения, будь то файл XML, база данных или даже хранилище авторизаций , с помощью диспетчера авторизации программного обеспечения Windows (который позволяет легко связать ваши пользовательские разрешения с LDAP). , в качестве одного примера - не требуется код для настройки).

Если вы решите использовать базу данных в качестве механизма хранения, будет поддерживаться несколько баз данных для автоматического создания базовых таблиц, которые необходимы платформе. Это включает в себя запуск .NET в Mono и использование модели поставщика ролей поверх MySQL.

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

РЕДАКТИРОВАТЬ : Я также должен указать, что конфигурация того, как ваше веб-приложение связывается с механизмом хранения, выполняется через файл web.config и не требует изменений кода. Я нашел это очень полезным для тестирования рабочей версии кодовой базы на моем локальном компьютере, используя XML-файл для имитации разрешений вместо обычного поставщика базы данных - и все это путем изменения двух строк в web.config.

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

2 голосов
/ 11 апреля 2009

Вы можете использовать Active Directory или другую реализацию LDAP, если вы находитесь в управляемой среде. Таким образом, группы безопасности, которые определяют разрешения, могут управляться поддержкой первой линии с использованием технологии, с которой они, скорее всего, уже знакомы.

Если ваше приложение упаковано в термоусадочную пленку, тогда +1 за предложение Леви Розоля о нормализации базы данных, чтобы в вашем приложении могла быть расширяемая модель данных.

1 голос
/ 14 октября 2008

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

Если вы думаете, что вам когда-нибудь понадобится выразительность, я бы пошел с полной системой ACL (список контроля доступа) с пользователями и группами (или ролями). То есть каждая вещь, управляемая разрешениями (например, «управлять пользователями», «управлять продуктами»), имеет ACL, представляющий собой список всех пользователей и групп, которые имеют к нему доступ. Затем пользователи либо добавляются непосредственно в соответствующие списки ACL, либо добавляются в группу, которая уже является членом ACL.

Хотя ACL предлагает реализацию списка, вам будет лучше с таблицей; этот ответ хороший способ.

0 голосов
/ 14 октября 2008

Разрешения обычно представляют собой ключевые слова со значением 1, 0 или нулем (что указывает на наследование). В битовой системе вы, вероятно, не сможете создать индексы для идентификатора пользователя и ключевого слова полномочий; вместо этого вам придется сканировать каждую запись, чтобы получить значение разрешения.

Я бы сказал, пойти на первый вариант. Мне кажется, лучшее решение:

create table permissions (
    user_id INT NOT Null,
    permission VARCHAR(255) NOT NULL,
    value TINYINT(1) NULL
)
alter table `permissions` ADD PRIMARY KEY ( `user_id` , `permission` ) 
...