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

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

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

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

Пожалуйста, дайте мне советы по этому поводу.

Спасибо заранее.

Ответ 1

1. Отмените действия по созданию и разрешению прав пользователя с атрибутом Authorize (Уведомить, что использование свойства Roles для AuthorizeAttribute требует реализации MemberhipProvider (стандартного или пользовательского) и регистрации его в 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 и указать роли, для которых доступно действие/контроллер: [Authorize("Customer, Manager, RegionalAdmin")] и дать администратору возможность назначать роли пользователям, Но помните, что в этом достаточно, чтобы быть доступным только в 1 из перечисленных ролей, вы не можете требовать от этого атрибута, например, роли администратора и менеджера. Если требуется потребовать более 1 роли, используйте несколько атрибутов:

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

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

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.Decorate(контроллеры), доступные для пользователей, предоставленных администратором:

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

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

Action3()
{
//...
}

}

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

Ответ 2

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

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, архитектуры, которая может быть легко упущена будущими разработчиками проекта.

Ответ 3

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

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

Ответ 4

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

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