Ответ 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()
{
//...
}
}
Я не рекомендую использовать базовый контроллер для этой цели, потому что использование атрибутов более гибкое (у вас есть контроль над уровнем действия/контроллера вместо уровня контроллера), это лучший способ реализовать разделенную ответственность. Базовый контроллер и использование атрибута фильтра коррелируются как полиморфизм и оператор переключения.