我有一个用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 修复之前,如果要对基于声明的授权使用声明性方法,则唯一真正的选择是重新实现 ClaimsPrincipalPermission
和 ClaimsPrincipalPermissionAttribute
。
我通过在类构造函数中使用CheckAccess
调用来解决此问题:
class SecuredClass
{
public SecuredClass()
{
ClaimsPrincipalPermission.CheckAccess("SecuredClass", "GeneralAccess");
}
[ClaimsPrincipalPermission(SecurityAction.Demand, Resource = "MethodLevelSecuredMethod", Operation = "Call")]
public void MethodLevelSecuredMethod()
{
Console.WriteLine("Called MethodLevelSecuredMethod");
}
}