2012-09-17 57 views
5

我想實現一個新的基於權限的訪問方法爲我的MVC應用程序;我們有幾個權限組,每個組包含一個權限的列表。例如我們有Invoices權限組,其中包含CreateInvoice,RemoveInvoice,etc權限密鑰。C#屬性:使用枚舉常量作爲輸入參數

在這種方法中,每個mvc Action應該需要執行的特定權限。我試圖通過CustomAttributes要做到這一點,是這樣的:

public class InvoiceController : Controller 
    { 
     [RequirePermission(Permissions.Invoices.CreateInvoice)] 
     public ActionResult Create() 
     { 
      return View(); 
     } 
    } 

爲了讓開發者更容易記住不同的權限組和權限密鑰我試圖創建權限的預定義列表應是權限組和權限密鑰的組合。但由於限制應用於使用C#中的屬性參數 我無法使它工作。 (我不想做一個額外的大enumurator,並把所有的許可密鑰在那裏

我最後一次嘗試是創造一個枚舉每個權限組,然後在裏面定義的許可密鑰爲枚舉常量:

public class PermissionEnums 
{ 
    [PermissionGroup(PermissionGroupCode.Invoice)] 
    public enum Invoices 
    { 
     CreateInvoice = 1, 
     UpdateInvoice = 2, 
     RemoveInvoice = 3, 
     ManageAttachments = 4 
    } 

    [PermissionGroup(PermissionGroupCode.UserAccounts)] 
    public enum UserAccounts 
    { 
     Create = 1, 
     ChangePassword = 2 
    } 
} 

正如您所見,我們在此處有一組代碼組合,其中使用PermissionGroup屬性指定的權限組密鑰以及每個枚舉常量上指定爲數字代碼的權限密鑰。

定義爲下面的RequirePermission屬性:

public class RequirePermissionAttribute : Attribute 
{ 
    private Enum _Permission; 

    public RequirePermissionAttribute(Enum Permission) 
     : base() 
    { 
     _Permission = Permission; 
    } 
} 

但問題是,Enum類型的對象不能被用作屬性參數。

任何建議/想法表示讚賞

回答

6

我發現解決方案,唯一需要改變的是結構參數的類型。而不是使用Enum,你必須使用object

public class RequirePermissionAttribute : AuthorizeAttribute 
{ 
    private object _Permission; 

    public RequirePermissionAttribute(object Permission) 
     : base() 
    { 
     _Permission = Permission; 
    } 
} 

下面是完整的代碼:

/***************** Permission Groups And Keys *****************/ 
public static class Permissions 
{ 
    [PermissionGroup(PermissionGroupCode.Invoice)] 
    public enum Invoices 
    { 
     CreateInvoice = 1, 
     UpdateInvoice = 2, 
     RemoveInvoice = 3, 
     ManageAttachments = 4 
    } 

    [PermissionGroup(PermissionGroupCode.UserAccounts)] 
    public enum UserAccounts 
    { 
     Create = 1, 
     ChangePassword = 2 
    } 
} 

public enum PermissionGroupCode 
{ 
    Invoice = 1, 
    UserAccounts = 2, 
    Members = 3 
} 

/***************** Attributes & ActionFilters *****************/ 

[AttributeUsage(AttributeTargets.Enum)] 
public class PermissionGroupAttribute : Attribute 
{ 
    private PermissionGroupCode _GroupCode; 
    public PermissionGroupCode GroupCode 
    { 
     get 
     { 
      return _GroupCode; 
     } 
    } 

    public PermissionGroupAttribute(PermissionGroupCode GroupCode) 
    { 
     _GroupCode = GroupCode; 
    } 
} 


public class RequirePermissionAttribute : AuthorizeAttribute 
{ 
    private object _RequiredPermission; 

    public RequirePermissionAttribute(object RequiredPermission) 
     : base() 
    { 
     _RequiredPermission = RequiredPermission; 
    } 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     var permissionGroupMetadata = (PermissionGroupAttribute)_RequiredPermission.GetType().GetCustomAttributes(typeof(PermissionGroupAttribute), false)[0]; 

     var groupCode = permissionGroupMetadata.GroupCode; 
     var permissionCode = Convert.ToInt32(_RequiredPermission); 

     return HasPermission(currentUserId, groupCode, permissionCode); 
    } 
} 
0

我不認爲這就是可能我試圖做你的事和失敗:/抱歉。

權限上的行動應與授權使用,你可以使自己的ovveride寫這樣的事情:

[AttributeUsage(AttributeTargets.All)] 
    public sealed class CustomAuthorizeAttribute : AuthorizeAttribute 
    { 

    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     if (httpContext == null) 
      throw new ArgumentNullException("httpContext"); 

     //Its a piece of code from my app you can modify it to suit your needs or use the base one 
     if (!new CustomIdentity(httpContext.User.Identity.Name).IsAuthenticated) 
     { 
      return false; 
     } 

     return true; 
    } 

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
    { 
     base.HandleUnauthorizedRequest(filterContext); 

    } 

} 

然後在你的行動:

[CustomAuthorizeAttribute(Roles = "FE")] 
public ActionResult Index() 
{ 
    return RedirectToAction("Index", "Documents"); 
} 

但它仍然是一個字符串,你使用和使用它需要將其與自定義角色提供程序結合使用。很麻煩,但在我看來值得。

+0

是的,我已經做了,但我的問題是沒有建立一個屬性(屬性ActionFilter)檢查用戶權限。我只需要一個更好的方法(比使用純字符串鍵)來創建預定義的權限常量。 – sos00

+1

http://www.vivienchevallier。com/Articles/create-a-custom-authorizeattribute-that-accepting-parameters-of-type-enum試試這個。 – AdrianCogiel