Как спроектировать объектную модель пользователя с использованием MS Roles & Membership - PullRequest
3 голосов
/ 17 января 2009

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

В основном я планирую иметь около 4 типов пользователей…, которые будут соответствовать «ролям» пользователей в поставщике членства.

Эти типы будут: • рабочий • Работодатель • Гость • Admin

Супер тип это: • Пользователь

Кроме того, пользователь может время от времени быть одновременно и «работником», и «работодателем».

Я хотел бы использовать поставщика ролей и членства MS и настроить пользовательский интерфейс навигации для ответа на роль пользователя.

Мой вопрос: Как я могу наилучшим образом спроектировать этих Пользователей, чтобы они были гибкими (Пользователь может быть Работником и Работодателем). Как мне обработать процедуру входа / роли?

(я имею в виду пользователя с фабрикой для объектов «поведение» (поведение работника, поведение работодателя))

При входе в систему при входе пользователя в систему ... находит свою роль и преобразует ее в подтип.

Это как это должно быть сделано?

Ответы [ 2 ]

3 голосов
/ 17 января 2009

Использование только понятия роли само по себе всегда было для меня адекватным. Это не обеспечивает достаточно низкую степень детализации для контроля разрешений. В качестве примера у вас может быть рабочая роль и роль администратора, а затем в коде вы используете Principal.IsInRole («Admin»), чтобы проверить их роль, чтобы определить, могут ли они изменить какое-то значение (скажем, оклад). Затем кто-то меняет свое мнение и говорит, что супервайзеры могут менять оклады, но все же не являются администраторами. Теперь вам нужно изменить проверку доступа, чтобы добавить еще одну проверку роли. Больно и рутино.

Итак, я делаю список всех функций в приложении, а затем позволяю им быть привязанными к роли в базе данных. Мои проверки доступа выглядят как принципал.HasPermission ("CHANGESALARY"). Я загружаю разрешения пользователей в зависимости от роли, к которой они присоединяются при входе в систему. Таким образом, компания может создать столько групп функций, сколько им нужно, и присвоить им имена. Затем они могут быть применены к любому пользователю.

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

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

1 голос
/ 28 января 2009

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

Мои роли - это все возможные комбинации разрешений:

Worker, Employee, Guest, Admin, WorkerEmployee, etc

В моем коде у меня есть перечисление для отдельных разрешений

[Flags]
public enum RolePermissions
{
    Guest = 1,
    Worker = 2,
    Employee = 4,
    Admin = 8
}

и у меня есть перечисление, соответствующее ролям в базе данных. Целочисленные значения являются побитовым ИЛИ разрешений:

public enum AvailableRoles
{
    None = 0,
    Guest = RolePermissions.Guest, //1
    Worker = RolePermissions.Worker, // 2
    Employee = RolePermissions.Employee, // 4
    WorkerEmployee = RolePermissions.Worker | RolePermissions.Employee, // 6
    Admin = RolePermissions.Admin, // 8
}

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

// Used to determine if the currently logged in user has a particular permission (Guest, Worker, Employee, Admin)
public static bool UserHasPermission( RolePermissions rolePermssion )
{
    foreach( string role in Roles.GetRolesForUser() )
    {
        AvailableRoles availableRole = Parse( role );

        if( ( (RolePermissions)availableRole & rolePermssion ) == rolePermssion )
            return true;
    }

    return false;
}

// Used to determine whether the currently logged in user is in a specific role
public static bool UserIsInRole( AvailableRoles requestedRole )
{
    return UserIsInRole( Membership.GetUser().UserName, requestedRole );
}

// Used to determine whether a specific user is in a specific role
public static bool UserIsInRole( string username, AvailableRoles requestedRole )
{
    foreach( string role in Roles.GetRolesForUser( username ) )
    {
        AvailableRoles actualRole = Parse( role );

        if( actualRole == requestedRole )
            return true;
    }

    return false;
}

// Helper method to parse enum
private static AvailableRoles Parse( string role )
{
    return (AvailableRoles)Enum.Parse( typeof( AvailableRoles ), role );
}

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

...