Подтвердить что ты не робот

Каков наилучший способ обработки нескольких типов разрешений?

Я часто сталкиваюсь со следующим сценарием, когда мне нужно предложить множество разных типов разрешений. Я в основном использую ASP.NET/VB.NET с SQL Server 2000.

Сценарий

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

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

1) Используйте единую таблицу разрешений со специальными столбцами, которые используются для определения того, как применять параметры. Специальные столбцы в этом примере - TypeID и TypeAuxID. SQL выглядел бы примерно так.

SELECT COUNT(PermissionID)
FROM application_permissions
WHERE
(TypeID = 1 AND TypeAuxID = @UserID) OR
(TypeID = 2 AND TypeAuxID = @DepartmentID)
AND ApplicationID = 1

2) Используйте таблицу сопоставления для каждого типа разрешений, а затем объедините их все вместе.

SELECT COUNT(perm.PermissionID)
FROM application_permissions perm
LEFT JOIN application_UserPermissions emp
ON perm.ApplicationID = emp.ApplicationID
LEFT JOIN application_DepartmentPermissions dept
ON perm.ApplicationID = dept.ApplicationID
WHERE [email protected]
  AND ([email protected] OR [email protected] OR
 (emp.UserID IS NULL AND dept.DeptID IS NULL)) AND ApplicationID = 1
ORDER BY q.QID ASC

Мои мысли

Надеюсь, что примеры имеют смысл. Я собрал их вместе.

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

4b9b3361

Ответ 1

Я согласен с Джоном Дауни.

Лично я иногда использую перечисление разрешений с флагом. Таким образом, вы можете использовать побитовые операции AND, OR, NOT и XOR для элементов перечисления.

"[Flags]
public enum Permission
{
    VIEWUSERS = 1, // 2^0 // 0000 0001
    EDITUSERS = 2, // 2^1 // 0000 0010
    VIEWPRODUCTS = 4, // 2^2 // 0000 0100
    EDITPRODUCTS = 8, // 2^3 // 0000 1000
    VIEWCLIENTS = 16, // 2^4 // 0001 0000
    EDITCLIENTS = 32, // 2^5 // 0010 0000
    DELETECLIENTS = 64, // 2^6 // 0100 0000
}"

Затем вы можете объединить несколько разрешений с помощью побитового оператора AND.

Например, если пользователь может просматривать и редактировать пользователей, двоичный результат операции 0000 0011, который преобразуется в десятичный, равен 3.
Затем вы можете сохранить разрешение одного пользователя в один столбец вашей базы данных (в нашем случае это будет 3).

Внутри приложения вам просто нужна другая побитовая операция (ИЛИ), чтобы проверить, имеет ли пользователь определенное разрешение или нет.

Ответ 2

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

  • Пользователи - это довольно прямолинейно, это ваша типичная таблица пользователей.
  • Группы - это будет синонимом ваших подразделений.
  • Роли - это таблица со всеми разрешениями, которая также включает в себя читаемое человеком имя и описание
  • Users_have_Groups - это таблица многих ко многим, какие группы принадлежит пользователю
  • Users_have_Roles - другая таблица "многие ко многим", какие роли назначаются отдельному пользователю.
  • Groups_have_Roles - окончательная таблица "многие-ко-многим", в каких ролях каждая группа имеет

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

Как я уже сказал, это то, что я обычно делаю, но ваш размер может отличаться.

Ответ 3

В дополнение к решениям John Downey и jdecuyper я также добавил бит "Явный отказ" в конце/начале битового поля, так что вы можете выполнять аддитивные разрешения по группам, членству в ролях, а затем вычесть разрешения на основе при явных запретах записи, как NTFS работает, разрешено.

Ответ 4

Честно говоря, функции членства/ролей ASP.NET будут отлично работать для описанного вами сценария. Написание собственных таблиц /procs/classes - отличное упражнение, и вы можете получить очень хороший контроль над мельчайшими деталями, но, сделав это сам, я решил лучше использовать встроенный материал .NET. Много существующего кода предназначено для работы вокруг него, что хорошо хорошо. Написание с нуля заняло у меня около 2 недель, и это было не так удобно, как .NET. Вы должны кодировать так много дерьма (восстановление пароля, автоматическая блокировка, шифрование, роли, интерфейс разрешений, тонны procs и т.д.), И время может быть лучше потрачено в другом месте.

Извините, если я не ответил на ваш вопрос, я как парень, который говорит, чтобы узнать С#, когда кто-то задает вопрос vb.

Ответ 5

Подход, который я использовал в различных приложениях, состоит в том, чтобы иметь общий класс PermissionToken, который имеет изменяемое свойство Value. Затем вы запрашиваете запрошенное приложение, оно сообщает вам, какие PermissionTokens необходимы для его использования.

Например, приложение "Доставка" может сказать вам, что вам нужно:

new PermissionToken()
{
    Target = PermissionTokenTarget.Application,
    Action = PermissionTokenAction.View,
    Value = "ShippingApp"
};

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