7

MVCアプリケーションに新しいアクセス許可ベースのアクセスアプローチを実装しようとしています。いくつかの権限グループがあり、各グループには権限のリストが含まれています。たとえば、パーミッションキーInvoicesを含むパーミッショングループがありCreateInvoice,RemoveInvoice,etcます。

このアプローチでは、各MVCActionを実行するために特定の権限が必要です。私はCustomAttributesを介してこれを行おうとしています。

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

開発者がさまざまなアクセス許可グループとアクセス許可キーを覚えやすくするために、アクセス許可グループとアクセス許可キーの組み合わせである必要があるアクセス許可の事前定義されたリストを作成しようとしています。しかし、C#での属性引数の使用に適用される制限のため、まだ機能させることができませんでした。(特大の列挙子を作成して、そこにすべての許可キーを入れたくありません

私の最後の試みは、各アクセス許可グループの列挙子を作成し、そこでアクセス許可キーを列挙型定数として定義することでした。

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属性引数として使用できないことです。

任意の提案/アイデアは大歓迎です

4

2 に答える 2

8

私は解決策を見つけました。変更する必要があるのは、構造パラメータのタイプだけです。使用する代わりに、使用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);
    }
}
于 2012-09-18T12:34:56.330 に答える
0

私はあなたのことをやろうとして失敗した可能性はないと思います:/ごめんなさい。

アクションの権限はAuthorizeで使用する必要があり、次のような独自の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");
}

ただし、それでも使用する文字列であり、それを機能させるには、カスタムロールプロバイダーと組み合わせる必要があります。多くの手間がかかりますが、私の意見ではそれだけの価値があります。

于 2012-09-18T06:51:14.867 に答える