Как разработать объектную модель пользователя с использованием ролей и членства в MS

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

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

Эти типы будут: • Работник • Работодатель • Гость • Администратор.

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

Вдобавок - Пользователь иногда может быть как «работником», так и «работодателем».

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

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

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

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

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


person Community    schedule 16.01.2009    source источник


Ответы (2)


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

Итак, что я делаю, это составляю список всех функций в приложении, а затем разрешаю их связать с ролью в базе данных. Мои проверки доступа выглядят как primary.HasPermission («ИЗМЕНЕНИЕ ЗАПЛАТЫ»). Я загружаю разрешения пользователей в зависимости от роли, к которой они привязаны, когда они входят в систему. Таким образом, компания может создавать столько групп функций, сколько они хотят, и давать им имена. Затем их можно применить к любому пользователю.

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

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

person DancesWithBamboo    schedule 16.01.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 );
}

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

person Greg    schedule 28.01.2009