2012-09-17 24 views
5

MVCアプリケーションに新しいアクセス権ベースのアクセス方法を実装しようとしています。 パーミッショングループがあり、各グループにパーミッションのリストが含まれています。たとえば、CreateInvoice,RemoveInvoice,etcパーミッションキーを含むInvoicesパーミッショングループがあります。C#の属性:enum定数を入力パラメータとして使用

このアプローチでは、各mvc Actionには実行のための特定の許可が必要です。それが簡単に開発者は、私がそのすべき権限の事前定義されたリストを作成しようとしている別のアクセス許可グループおよびアクセス許可のキーを覚えてできるようにすること

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

:私は、CustomAttributesを介してこれを行うには、このような何かをしようとしていますパーミッショングループとパーミッションキーの組み合わせ。 C# で属性の引数を使用する際に適用される制限のため、まだ動作させることができませんでした。私の最後の試みは、各権限グループの列挙子を作成し、そこでのenum定数として許可キーを定義して(私は特大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を行うことができます。あなたがそのまだ文字列

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

[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); 

    } 

} 

、あなたの行動にを使用するためには、カスタムロールプロバイダと組み合わせる必要があります。私の意見ではそれほど価値があるが価値がある。

+0

うん、私はそれをやったが、私の問題は、チェックする(属性のActionFilter)属性を作成されていませんユーザーのアクセス許可。私は、あらかじめ定義されたパーミッション定数を作成するために、単純な文字列キーを使用するよりも良い方法が必要です。 – sos00

+1

http://www.vivienchevallier。com/Articles/create-a-custom-authorizeattribute-that-accepts-parameters-of-type-enumこれを試してください。 – AdrianCogiel

関連する問題