Ролевое управление в MVC3 - PullRequest
11 голосов
/ 07 июня 2011

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

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

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

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

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

Ответы [ 4 ]

13 голосов
/ 07 июня 2011

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")] и дать администратору возможность назначать роли пользователям , Но помните, что для того, чтобы получить доступ, достаточно быть только в одной из перечисленных ролей, вы не можете требовать по этому атрибуту, например, роли «Администратор» и «Менеджер». Если вы хотите обязательно указать более одной роли, используйте несколько атрибутов:

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

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

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

Action3()
{
//...
}

}

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

4 голосов
/ 07 июня 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, чтобы обернуть таблицу с именем «User», и затем в ваших контроллерах вы сможете получить доступ к любым полям в этой таблице.

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

2 голосов
/ 07 июня 2011

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

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

1 голос
/ 03 августа 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...