2011-02-25 35 views
4

我忙着写我自己的自定义属性我叫MyAuthorizeAttribute操作方法,我还在忙着写代码,这里是我的部分代码:如何延长AuthorizeAttribute并检查用户的角色

[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 
} 

我的操作方法:

原因为什么我没有使用角色=“管理员,超级管理员”是因为角色是硬编码的。如果角色名称发生变化,我不希望有100个地方可以更改。

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

我在这里正确吗?如果不是,我会如何执行此操作?它不一定是我做它的方式。

+0

是由以下任何两个答案来解决问题了吗?如果是,请接受答案。它会帮助像我一样有同样问题的其他人。 – 2013-11-21 12:49:35

回答

2

如果我理解正确,这里的问题不是继承AuthorizeAttribute,而是通过比较枚举值。您可能需要一个枚举类型,您可以使用它作为位标志 - 如果是,请查看the section about Enumeration Types in the C# Programming guide,尤其是第二部分“枚举类型作为位标志”。

要澄清一点:

而不只是检查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, i.e. 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; 
    } 
} 
+0

是我分配的角色,我想检查用户是否在角色中。它不一定是这样,它只是我,可能有更好的方法来实现这一点。 – 2011-02-25 13:42:25

+0

我不明白这将如何帮助我? – 2011-02-25 13:45:42

+0

@Brendan:请参阅我的更新。 – 2011-02-25 14:28:07

4

这岂不是更好,如果MyAuthorizeAttribute接受一个I​​List(或类似) 这样,它是两个类型安全,但你不必使用位标志。 如果你想保存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<string>(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) 
     { 
      return false; 
     }*/ 
     if ((RoleList.Length > 0) && !RoleList.Select(p=>p.ToString()).Any<string>(new Func<string, bool>(user.IsInRole))) 
     { 
      return false; 
     } 
     return true; 
    } 

} 

控制器:

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

您介意提供代表您的意思的代码示例吗? – 2011-02-25 14:08:36

+0

@Brendan:添加了示例。 – Tomas 2011-02-25 14:40:18

相关问题