Каков наилучший способ управления разрешениями для веб-приложения - битмаска или таблицы базы данных?
Я рассматриваю лучший способ разработки системы разрешений для веб-приложения "admin". В приложении, вероятно, будет много пользователей, каждому из которых может быть назначена определенная роль; некоторым из этих пользователей может быть разрешено выполнять определенные задачи вне роли.
Я могу подумать о двух способах создания этого: один, с таблицей "разрешений" со строкой для каждого пользователя и булевыми столбцами, по одному для каждой задачи, которые назначают им разрешения для выполнения этих задач. Вот так:
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
Какие механизмы обычно используют люди, и почему?
Спасибо!
Ответы
Ответ 1
Я думаю, что это общее правило, чтобы держаться подальше от мистических бистрон, которые кодируют смысл вселенной.
Хотя, возможно, более clunkier, имея таблицу возможных разрешений, таблицу пользователей и таблицу ссылок между ними - лучший и самый ясный способ организовать это. Это также упрощает ваши запросы и обслуживание (особенно для нового парня).
Ответ 2
как создать таблицу Permission, а затем таблицу UserPermission для хранения отношений?
Вам больше не придется изменять структуру, и у вас есть возможность добавить столько разрешений, сколько пожелаете.
Ответ 3
Я сделал это в обоих направлениях. Но я больше не использую битовые маски. Отдельная таблица будет полезна, так как вы можете использовать ее в качестве перекрестной ссылки, учитывая идентификатор пользователя или идентификатор группы в качестве внешнего ключа.
UserID | Permission
===================
1 | 1 1 representing manage users
1 | 2 2 being manger products
2 | 3
Таким образом было бы легче поддерживать и добавлять дальше.
Я бы также использовал отдельную таблицу для управления разрешениями.
PermissionID | Description
==========================
1 | Manage Users
2 | Manager Products
Ответ 4
Обычно у меня есть таблица Users, таблица Roles и таблица UserRoles. Таким образом, вы можете иметь неограниченное количество ролей, не изменяя структуру своего db, и пользователи могут быть в нескольких ролях.
Я заставляю приложение разрешать только роли (никогда не пользователям). Обратите внимание, что столбец "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
)
Ответ 5
Я предлагаю абстрагировать разрешения вашего веб-приложения с концепцией поставщика роли. Начиная с версии 2.0, это предусмотрено для вас в .NET как System.Web.Security.RoleProvider.
Основная идея заключается в том, что вы используете существующую инфраструктуру, написав свои проверки на соответствие структуре, а не конкретному механизму хранения. Затем вы можете подключить любой механизм хранения, будь то файл XML, базу данных или даже хранилище авторизации с помощью программного обеспечения Windows Authorization Manager (который позволяет вам легко привязывать свои пользовательские разрешения к LDAP, как один пример - никакого кода, который требуется для настройки).
Если вы решили использовать базу данных в качестве механизма хранения, поддерживаются несколько баз данных для автоматического создания базовых таблиц, которые необходимы инфраструктуре. Это включает в себя запуск .NET на Mono и использование модели поставщика ролей поверх MySQL.
Для получения дополнительной информации см. Внедрение поставщика ролей. Вполне возможно, что на других языках/средах также есть библиотеки, которые вы могли бы использовать для реализации этой концепции, - было бы интересно изучить.
РЕДАКТИРОВАТЬ. Я также должен указать, как настраивается ваше веб-приложение в механизм хранения через файл web.config и не требует изменений кода. Я нашел это очень полезным для тестирования производственной версии кодовой базы на моей локальной машине, используя XML файл для имитации разрешений вместо обычного поставщика базы данных - все путем изменения двух строк в web.config.
Другая вещь, о которой я забыл упомянуть, заключается в том, что вы можете подключать собственные собственные поставщики, расширяя базовые классы, позволяя использовать модель разрешений, но при этом использовать запатентованную систему хранения (например, бит-маски, если вы действительно хотел).
Ответ 6
Вы можете использовать Active Directory или другую реализацию LDAP, если находитесь в управляемой среде. Таким образом, группы безопасности, которые определяют разрешения, могут управляться поддержкой первой линии, используя технологию, с которой они, скорее всего, уже знакомы.
Если ваше приложение сжато, то +1 для предложения Levi Rosol о нормализации базы данных, чтобы вы могли иметь расширяемую модель данных в своем приложении.
Ответ 7
Я видел несколько несколько ограниченных систем разрешений, похожих на то, что вы предлагаете, а также некоторые действительно ужасные системы. В некоторых простых ситуациях они могут быть приемлемыми, если приложение не становится более сложным. Однако во многих случаях они становятся более сложными, и системы должны быть переписаны для обеспечения требуемой функциональности.
Если вы считаете, что когда-нибудь понадобится выразительность, я бы пошел с полным списком управления доступом (ACL) с пользователями и группами (или ролями). То есть, каждая вещь, управляемая разрешениями (например, "управлять пользователями", "управлять продуктами" ), имеет ACL, который является списком всех пользователей и групп, которые имеют к нему доступ. Затем пользователи либо добавляются непосредственно в соответствующие списки ACL, либо добавляются в группу, которая уже является членом ACL.
Хотя ACL предлагает реализацию списка, вам будет лучше с таблицей; этот ответ является хорошим способом.
Ответ 8
Разрешения - это обычно ключевые слова с 1, 0 или null (указывающие наследование). С битовой системой вы, вероятно, не можете создавать индексы на идентификаторе пользователя и ключевом слове разрешений; вместо этого вам нужно будет сканировать каждую запись, чтобы получить значение разрешения.
Я бы сказал, для первого варианта. Мне кажется лучшим решением:
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` )
Ответ 9
Не могу комментировать, потому что я новичок в SO, но в отношении принятого ответа - огромное преимущество, которое приходит с этим решением, - это возможность универсально обрабатывать разрешения, а не просто операторы везде в коде, а также специальные возможности например, разрешение временных разрешений (разрешений, срок действия которых истекает)