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

StackOverflow https://stackoverflow.com/questions/1451

  •  08-06-2019
  •  | 
  •  

Вопрос

Я часто сталкиваюсь со следующим сценарием, когда мне нужно предложить множество различных типов разрешений.В основном я использую 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 q.SectionID=@SectionID
      AND (emp.UserID=@UserID OR dept.DeptID=@DeptID OR
     (emp.UserID IS NULL AND dept.DeptID IS NULL)) AND ApplicationID = 1
    ORDER BY q.QID ASC
    

Мои мысли

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

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

Это было полезно?

Решение

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

Лично я иногда использую помеченное перечисление разрешений.Таким образом, вы можете использовать побитовые операции 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).

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

Другие советы

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

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

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

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

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

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

Извините, если я не ответил на ваш вопрос, я похож на парня, который говорит, что надо выучить C#, когда кто-то задает вопрос по VB.

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

Например, приложение «Доставка» может сообщить вам, что ему необходимо:

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top