我的 ASP.NET MVC4 Web 应用程序有一个自定义主体/身份。我还创建了一个 AuthorizeAttribute 来实例化我的自定义主体,将其分配给我需要身份验证的 Controller 中的 httpContext.User。
这对于使用我的 AuthorizeAttribute 修饰的 Controller /操作非常有用但是,对于不需要身份验证的 Controller (但如果存在,仍然使用它),我想获取我的 CustomPrincipal(最好通过 HttpContext.User) .
在这些未修饰的 Controller /操作中,设置了 HttpContext.User,但使用的是 GenericPrincipal 而不是我的 CustomPrincipal。 将 HttpContext.User 的默认设置“覆盖”到 GenericPrincipal 的最佳位置在哪里?
同样,如果在每个具有身份验证 cookie 的请求中都这样做,在 AuthorizeAttribute 修饰的 Controller 的情况下,我将如何避免做两次工作(这将成为一个强制认证)。
为了清楚起见,我的网站允许匿名用户访问,但在这些页面上,如果一个经过身份验证(并且实现了 CustomPrincipal),则提供了额外的功能。
我认为一些选项是(不确定每个选项背后的逻辑):
想法?
最佳答案
您可以使用全局操作过滤器。假设您有一个自定义主体:
public class MyPrincipal : GenericPrincipal
{
public MyPrincipal(IIdentity identity, string[] roles): base(identity, roles)
{
}
... some custom properties and stuff
}
那么你可以编写一个全局授权操作过滤器(但它不是从基础
AuthorizeAttribute
派生来避免全局身份验证,它只是实现了 IAuthorizationFilter
接口(interface)以确保它在任何其他过滤器之前运行):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());
}
}
现在您可以拥有一个自定义授权属性,该属性仅适用于某些需要身份验证的 Controller 操作:
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;
}
}
然后你可以有两种类型的 Action :
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
...
}
关于asp.net - 如何全局创建 CustomPrincipal(有和没有 AuthorizeAttribute),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11476301/