Я создаю простой CMS, в котором роли установлены динамично в панели администрации. Существующий способ авторизовать метод контроллера, добавляя [Authorize(Roles="admin")]
например, больше не поэтому достаточно. Отношения ролевого действия должны быть сохранены в базе данных, так, чтобы конечные пользователи могли легко давать/брать полномочия другим в панели администрации. Как я могу реализовать это?
Если вы хотите взять под контроль процесс авторизации, вы должны создать подкласс AuthorizeAttribute и переопределить метод AuthorizeCore . Затем просто украсьте свои контроллеры своим CmsAuthorizeAttribute
вместо значения по умолчанию.
public class CmsAuthorizeAttribute : AuthorizeAttribute
{
public override virtual bool AuthorizeCore(HttpContextBase httpContext)
{
IPrincipal user = httpContext.User;
IIdentity identity = user.Identity;
if (!identity.IsAuthenticated) {
return false;
}
bool isAuthorized = true;
// TODO: perform custom authorization against the CMS
return isAuthorized;
}
}
Обратной стороной этого является то, что у вас не будет доступа к IoC, внедренному ctor, поэтому вам придется запрашивать любые зависимости напрямую из контейнера.
Это именно то, что делает для вас членство / профиль ASP.NET. И это работает с атрибутом Authorize.
Если вы хотите использовать свой собственный, вы можете создать фильтр настраиваемых действий, который имитирует поведение стандартного фильтра действий авторизации. Псевдокод ниже.
public MyAuthorizeAttribute : ActionFilterAttribute
{
public string MyRole { get; set; }
public void OnActionExecuting(ControllerContext context)
{
if (!(bool)Session["userIsAuthenticated"])
{
throw new AuthenticationException("Must log in.");
}
if (!Session["userRoles"].Contains(MyRole))
{
throw new AuthenticationException("Must have role " + MyRole);
}
}
}
Связь роль-действие должна храниться в базе данных
. Вам нужно будет проверить свою безопасность с помощью метода контроллера, если только вы хотите создать подкласс AuthorizeAttribute
, чтобы он выполнял поиск ролей в базе данных за вас.