Ответ 1
Вы можете использовать глобальный фильтр действий. Предположим, что у вас есть пользовательский принцип:
public class MyPrincipal : GenericPrincipal
{
public MyPrincipal(IIdentity identity, string[] roles): base(identity, roles)
{
}
... some custom properties and stuff
}
тогда вы можете написать глобальный фильтр действий авторизации (но который не вытекает из базы AuthorizeAttribute
, чтобы избежать глобальной аутентификации, он просто реализует интерфейс IAuthorizationFilter
, чтобы гарантировать, что он выполняется перед любыми другими фильтрами):
public class GlobalIdentityInjector : ActionFilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
var identity = filterContext.HttpContext.User.Identity;
// do some stuff here and assign a custom principal:
var principal = new MyPrincipal(identity, null);
// here you can assign some custom property that every user
// (even the non-authenticated have)
// set the custom principal
filterContext.HttpContext.User = principal;
}
}
Глобальный фильтр будет зарегистрирован в ~/App_Start/FilterConfig.cs
, чтобы гарантировать, что он будет применяться ко всем действиям:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new GlobalIdentityInjector());
}
}
И теперь у вас может быть настраиваемый атрибут авторизации, который будет применяться только к определенным действиям контроллера, требующим проверки подлинности:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var authorized = base.AuthorizeCore(httpContext);
if (!authorized)
{
return false;
}
// we know that at this stage we have our custom
// principal injected by the global action filter
var myPrincipal = (MyPrincipal)httpContext.User;
// do some additional work here to enrich this custom principal
// by setting some other properties that apply only to
// authenticated users
return true;
}
}
и тогда у вас может быть 2 типа действий:
public ActionResult Foo()
{
var user = (MyPrincipal)User;
// work with the custom properties that apply only
// to anonymous users
...
}
[MyAuthorize]
public ActionResult Bar()
{
var user = (MyPrincipal)User;
// here you can work with all the properties
// because we know that the custom authorization
// attribute set them and the global filter set the other properties
...
}