在类级别和方法级别应用 ClaimsPrincipalPermissionAttribute 时出现异常



我有一个用ClaimsPrincipalPermissionsAttribute装饰的类。该类有一个方法,该方法也用 ClaimsPrincipalPermissionsAttribute 进行装饰。我所期望的是:

首先,当我实例化类时,我收到对我的自定义ClaimsAuthorizationManager的调用。这按预期工作。

其次,当我调用该方法时,我收到两次对ClaimsAuthorizationManager的调用。一个包含类级别属性中的"资源和操作",另一个包含方法级别属性中的"资源和操作"。这行不通。相反,当我调用该方法时,我会抛出一个SecurityException。异常消息为:

解码嵌入的权限集对象失败。

为了尝试查看发生了什么,我通过从 ClaimsPrincipalPermissionsAttribute 复制代码创建了一个自定义属性。我可以看到CreatePermission()方法在我的属性上调用,它成功返回了 ClaimsPrincipalPermission,但在调用我的 ClaimsAuthorizationManager 之前抛出了异常。

我的代码如下所示:

using System;
using System.IdentityModel.Services;
using System.Security.Permissions;
namespace ConsoleApplication5
{
    class Program
    {
        static void Main(string[] args)
        {
            var test = new SecuredClass();
            test.MethodLevelSecuredMethod();
            Console.ReadKey();
        }
    }
    [ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "SecuredClass", Operation = "GeneralAccess")]
    class SecuredClass
    {
        [ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "MethodLevelSecuredMethod", Operation = "Call")]
        public void MethodLevelSecuredMethod()
        {
            Console.WriteLine("Called MethodLevelSecuredMethod");
        }
    }
}

我做错了什么?是否可以在类和方法级别声明属性?

我正在使用.Net 4.5。

出现此问题是因为ClaimsPrincipalPermission没有实现采用PermissionState参数的公共构造函数。 (在 http://msdn.microsoft.com/en-us/library/vstudio/yaah0wb2.aspx 中记录了这样做的必要性,尽管隐藏在文本的中间。

这本质上是框架中的一个错误,可能应该在 https://connect.microsoft.com/visualstudio/feedback 报告。 如果这样做,您可能希望添加 FxCop 规则来检查此构造函数是否存在也可能是一个好主意。

在等待 bug 修复之前,如果要对基于声明的授权使用声明性方法,则唯一真正的选择是重新实现 ClaimsPrincipalPermissionClaimsPrincipalPermissionAttribute

我通过在类构造函数中使用CheckAccess调用来解决此问题:

class SecuredClass
{
    public SecuredClass()
    {
        ClaimsPrincipalPermission.CheckAccess("SecuredClass", "GeneralAccess");
    }
    [ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "MethodLevelSecuredMethod", Operation = "Call")]
    public void MethodLevelSecuredMethod()
    {
        Console.WriteLine("Called MethodLevelSecuredMethod");
    }
}

相关内容

  • 没有找到相关文章

最新更新