如何扩展AuthorizeAttribute并检查用户的角色

我正忙着为我的动作方法MyAuthorizeAttribute编写自己的自定义属性,我仍在忙于编写代码,这里是我的部分代码:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class MyAuthorizeAttribute : AuthorizeAttribute { public new Role Roles; public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); if (Roles != 0) // Did it this way to see what the value of Roles was return; // Here I am going to get a list of user roles // I'm doing my own database calls filterContext.Result = new HttpUnauthorizedResult(); } } 

这是我的角色枚举:

 public enum Role { Administrator = 1, SuperAdministrator = 2 } 

我的行动方法:

 [MyAuthorize(Roles = Role.Administrator|Role.SuperAdministrator)] public ActionResult Create() { return View(); } 

我没有使用Roles =“Administrator,SuperAdministrator”的原因是角色是硬编码的。 如果角色名称更改,我不希望有100个地方可以更改。

根据我的方法,当它到达if(Roles!= 0)然后Roles总值为3时,我如何检查这两个角色是否在特定用户的用户角色列表中?

我在这里做得对吗? 如果不是,我将如何实现这一点? 它不一定是我做的方式。

如果MyAuthorizeAttribute接受IList(或类似的),那么它是不是更好,这样既有类型安全,但你不必使用位标志。 如果你想保存reult,那么位标志很棒,但这是另一种方式。

编辑(现在有例子):

 Attribute: [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class MyAuthorizeAttribute : AuthorizeAttribute { public Role[] RoleList { get; set; } protected override bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext == null) { throw new ArgumentNullException("httpContext"); } IPrincipal user = httpContext.User; if (!user.Identity.IsAuthenticated) { return false; } //Only role access is implemented here /*if ((this._usersSplit.Length > 0) && !this._usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) { return false; }*/ if ((RoleList.Length > 0) && !RoleList.Select(p=>p.ToString()).Any(new Func(user.IsInRole))) { return false; } return true; } } 

控制器:

 [MyAuthorize(RoleList = new []{Role.Administrator , Role.SuperAdministrator} )] public ActionResult Create() { return View(); } 

如果我理解正确,那么你的问题不在于inheritanceAuthorizeAttribute ,而在于比较枚举值。 您可能需要一个可用作位标志的枚举类型 – 如果是这样,请查看C#编程指南中有关枚举类型的部分,尤其是第二部分“枚举类型为位标志”。

澄清一下:

而不只是检查Roles!=0 ,你现在可以做这样的事情:

 public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); // Here you get an enum indicating the roles this user is in. The method // converts the db information to a Role enum before it is returned. // If the user is not authenticated, the flag should not be set, ie equal 0. Role userRole = GetUserRolesFromDatabase(); // Bitwise comparison of the two role collections. if (Roles & userRole > 0) { // The user is in at least one of the roles in Roles. Return normally. return; } // If we haven't returned yet, the user doesn't have the required privileges. new HttpUnauthorizedResult(); } 

为了使比较更容易,您可以在枚举上使用以下扩展方法:

 public static class RolesExtensions { public static bool HasAnyOf(this Roles r1, Roles roles) { return (r1 & roles) > 0; } }