我想实现一个默认应用[Authorize(Roles = "Admin")]
属性的白名单方法。然后,我想在列入白名单的操作中指定[AllowAnonymous]
或[AllowMember]
。
所以我需要创建一个类似于AllowAnonymous
的属性,但只允许访问“Member”角色。 (与AllowAnonymous
一样,它应该覆盖可能在控制器上作为全局过滤器生效的任何Authorize
属性。)
我最初尝试从AllowAnonymousAttribute
继承,但我发现它已被封存。我用谷歌搜索“继承允许匿名”但答案让我脱离了我的深度。
我的方法是否明智,我如何创建这样的属性?
更新
按照NightOwl888的建议和this page的一些代码,我有:
创建了两个Attributes
,一个允许成员,另一个是公共
继承AuthorizeAttribute以创建一个新的 申请作为全球过滤器
在AuthorizeCore()方法中插入了几个方法,检查属性并返回true
我希望我在下面的代码中没有做任何愚蠢的事情......如果它看起来不错(或者没有),我会很感激。
感谢。
namespace FP.Codebase.Attributes
{
public class AllowPublicAccessAttribute : Attribute
{}
public class AllowMemberAccessAttribute : Attribute
{}
public class MyAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
filterContext.HttpContext.Items["ActionDescriptor"] = filterContext.ActionDescriptor;
base.OnAuthorization(filterContext);
}
private bool IsAllowPublicAccessAttributeAppliedToAction(ActionDescriptor actionDescriptor)
{
return (actionDescriptor.IsDefined(typeof(AllowPublicAccessAttribute), inherit: true)
|| actionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowPublicAccessAttribute), inherit: true));
}
private bool IsAllowMemberAccessAttributeAppliedToAction(ActionDescriptor actionDescriptor)
{
return (actionDescriptor.IsDefined(typeof(AllowMemberAccessAttribute), inherit: true)
|| actionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowMemberAccessAttribute), inherit: true));
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var actionDescriptor = httpContext.Items["ActionDescriptor"] as ActionDescriptor;
if (httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
IPrincipal user = httpContext.User;
if (IsAllowPublicAccessAttributeAppliedToAction(actionDescriptor))
{
return true;
}
if (IsAllowMemberAccessAttributeAppliedToAction(actionDescriptor) && user.IsInRole("Member"))
{
return true;
}
if (!user.Identity.IsAuthenticated)
{
return false;
}
var _usersSplit = SplitString(Users);
var _rolesSplit = SplitString(Roles);
if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
{
return false;
}
if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole))
{
return false;
}
return true;
}
// copied from https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/AuthorizeAttribute.cs
internal static string[] SplitString(string original)
{
if (String.IsNullOrEmpty(original))
{
return new string[0];
}
var split = from piece in original.Split(',')
let trimmed = piece.Trim()
where !String.IsNullOrEmpty(trimmed)
select trimmed;
return split.ToArray();
}
}
}
答案 0 :(得分:1)
AllowAnonymous
属性的所有行为都是coded into the AuthorizeAttribute.OnAuthorize
method。因此,如果您想重用此行为,最好的方法是继承AuthorizeAttribute
并覆盖AuthorizeCore
method。