Управление ролями в MVC3

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

Он может создавать роли и может предоставлять пользователям разные роли.

Я использую Visual Studio 2010 и создаю это приложение в MVC3.

Пожалуйста, дайте мне предложения, чтобы сделать над ним.

Заранее спасибо.


person kapil    schedule 07.06.2011    source источник


Ответы (4)


1. Украсьте действия по созданию пользователя и настройке разрешений атрибутом Authorize (уведомите, что использование свойства Roles в AuthorizeAttribute требует реализации MembershipProvider (стандартного или пользовательского) и его регистрации в web.config)

public class AccountController : Controller
{
[HttpGet, Authorize(Roles = "Admin")]
public ViewResult CreateUser()
{
    return View();
}

[HttpPost, Authorize(Roles = "Admin")]
public ActionResult CreateUser()
{
    //... call service method to create user
}

[HttpPost, Authorize(Roles = "Admin")]
public ActionResult AssignPageToUser(int userId, string controllerName, string ActionName)
{
    //... insert record into table (UserPermissions) with attributes (userId, actionName, controllerName)
    }
// other methods without decoration by authorize attribute
}

Следующие абзацы верны, если вы действительно хотите иметь полный контроль над разрешениями на действия отдельно для каждого пользователя. Если вы считаете, что ваши разрешения могут группироваться в конечном и небольшом количестве по ролям - вы можете оформить все действия/контроллеры атрибутом авторизации и указать роли, для которых доступно действие/контроллер: [Authorize("Customer, Manager, RegionalAdmin")] и дать админу возможность назначать роли пользователям. Но помните, что для получения доступа достаточно быть только в 1 из перечисленных ролей, по этому атрибуту нельзя требовать, например, и роли Администратора, и Менеджера. Если вы хотите требовать обязательно более 1 роли, используйте несколько атрибутов:

public class MyController:Controller
{
[Authorize(Roles = "Manager")]
[Authorize(Roles = "Admin")]
public ActionResult Action1()
{
//...
}
}

2. Для своих страниц вы можете создать свой собственный атрибут фильтра, унаследованный от атрибута авторизации, который будет проверять, доступно ли действие для пользователя (я думаю, вы хотите назначать пользователю действия, но не просмотры).

public UserPermissionRequiredAttribute: AuthorizeAttribute
{
public OnAuthorization(AuthorizationContext filterContext)
{
var isAuthenticated = filterContext.HttpContext.User.Identity.IsAuthenticated;
var userName = filterContext.HttpContext.User.Identity.Name;
var actionName = filterContext.ActionDescriptior.ActionName;
var controllerName = filterContext.ActionDescriptior.ControllerDescriptor.ControllerName;
    if (isAuthenticated && myUserActionPermissionsService.UserCanAccessAction(userName, actionName, contollerName)
{
filterContext.Result = HttpUnauthorizedResult(); // aborts action executing
}
}
}

3.Декорировать действия (контроллеры), доступные для пользователей, предоставленных администратором:

MySpecialController: Controller
{
[UserPermissionRequired]
Action1()
{
//...
}

[UserPermissionRequired]
Action2()
{
//...
}

Action3()
{
//...
}

}

Я не рекомендую использовать базовый контроллер для этой цели, потому что использование атрибута более гибкое (у вас есть контроль на уровне действия/контроллера, а не только на уровне контроллера), это лучший способ реализовать разделенную ответственность. Использование базового контроллера и атрибута фильтра коррелирует как полиморфизм и оператор переключения.

person Evgeny Levin    schedule 07.06.2011

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

public class MegaController
{
    protected User CurrentUser { get; set; }

    protected override void Initialize(RequestContext context)
    {
        if (requestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            var userRepository = new UserRepository();
            CurrentUser = userRepository.GetUser(
                requestContext.HttpContext.User.Identity.Name);
        }
    }
}

Типы User и UserRepository могут быть вашим собственным дизайном. Вы можете использовать LINQ To Entities для обертывания таблицы с именем «Пользователь», а затем в своих контроллерах вы можете получить доступ к любым полям в этой таблице.

Затем создайте подклассы всех контроллеров из MegaController

public class AdminController : MegaController
{
    public ActionResult Action1()
    {
        return View();
    }
}

public class SomeOtherController : MegaController
{
    public ActionResult Action1()
    {
        return View();
    }
}

Теперь это не полностью решает вашу проблему с «админом». Для этого вы можете включить логику в MegaController.Initialize() для запроса информации запроса. Как только у вас есть запрошенный маршрут и пользователь в контексте, ваш код может принять решение, разрешить ли запрос, перенаправить его и т. д.

protected override void Initialize(RequestContext context)
{
    // ...
    if(context.HttpContext != null)
    {
        if(context.HttpContext.Request.Path == "some/restricted/route" 
            && CurrentUser.Role != "Admin")
        {
            // or similar error page
            var url = Url.Action("UnAuthorized", "Error");
            context.HttpContext.Response.Redirect(url);
        }
    }
}

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

person David Fox    schedule 07.06.2011
comment
есть ли какой-либо учебник, который может помочь мне в этом. - person kapil; 07.06.2011
comment
@kapil Я не мог бы рекомендовать какую-либо документацию без дополнительных требований. Можете ли вы уточнить в своем исходном сообщении? - person David Fox; 07.06.2011

Прочтите о старой доброй аутентификации с помощью форм, чтобы добавить поддержку ролей и управления пользователями.

Затем используйте [Authorize(Roles="RoleName1")] на контроллерах или действиях для управления доступом.

person jgauffin    schedule 07.06.2011

Проверьте MvcMembership, также доступный на Nuget. У вас будут все основы для управления пользователями на сайте ASP.NET MVC 3.

Вам понадобится провайдер пользователя/роли. Чтобы узнать, как настроить база данных, в которой будут храниться ваши пользователи и роли. После настройки у вас будут созданы все хранимые процедуры, необходимые для первой настройки / ручного тестирования.

person Matthieu    schedule 03.08.2011