我创建了一个CodeAccessSecurityAttribute实现,使用堆栈信息来查找目标类名,但是在某些类中没有创建PrincipalPermition,系统使用预览一个。我错过了什么?
[ComVisible(true)]
[AttributeUsageAttribute(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public sealed class MyPrincipalPermissionAttribute : CodeAccessSecurityAttribute
{
public MyPrincipalPermissionAttribute(SecurityAction action) : base(action) { }
public override IPermission CreatePermission()
{
if (Unrestricted)
return new PrincipalPermission(PermissionState.Unrestricted);
var stackTrace = new StackTrace();
var fullnameArray = new List<String>();
foreach (var frame in stackTrace.GetFrames())
{
try
{
var method = frame.GetMethod();
if (method != null && method.ReflectedType.IsSubclassOf(typeof (BaseClass)))
fullnameArray.Add(method.ReflectedType.FullName);
} catch {}
}
if (fullnameArray.Count() > 0)
return new PrincipalPermission(null, fullnameArray[0], true);
return new PrincipalPermission(PermissionState.Unrestricted);
}
}
用法
public class MyClassCalledFirstWork: BaseClass
{
[MyPrincipalPermission(SecurityAction.Demand)]
public override void DoSomething()
{
return;
}
}
public class MyClassCalledSecondDontWork: BaseClass
{
[MyPrincipalPermission(SecurityAction.Demand)]
public override void DoSomething()
{
return;
}
}
答案 0 :(得分:1)
这是来自documentation的SecurityAttribute.CreatePermission():
“CreatePermission方法创建一个 然后可以是权限对象 序列化为二进制形式和 持续存储与 程序集中的SecurityAction 元数据。“
“在编译时, 属性转换安全性 对序列化表单的声明 元数据。声明性安全数据 元数据是从 此方法返回的权限 对应于此属性。“
看起来只有一个权限对象(某种类型)与为特定SecurityAction存储的自定义CodeAccessSecurityAttribute相对应。 当您检查IL for DoSomething方法时,您可以看到它们包含相同的权限要求,并且在第一次CreatePermission调用期间定义了角色。
.method public hidebysig virtual instance void
DoSomething() cil managed
{
.permissionset demand
= {class 'CustomSecurityPermission.Program+MyPrincipalPermissionAttribute, CustomSecurityPermission, Version=1.0.0.0, Culture=neutral' = {}}
...
} // end of method MyClassCalledSecondDontWork::DoSomething
.method public hidebysig virtual instance void
DoSomething() cil managed
{
.permissionset demand
= {class 'CustomSecurityPermission.Program+MyPrincipalPermissionAttribute, CustomSecurityPermission, Version=1.0.0.0, Culture=neutral' = {}}
...
} // end of method MyClassCalledFirstWork::DoSomething
评论中第二个问题的答案是:
而不是使用声明性CAS我将使用命令式:
public sealed class Security
{
public static IPermission CreatePermission()
{
var stackTrace = new StackTrace();
var fullnameArray = new List<String>();
foreach (var frame in stackTrace.GetFrames())
{
try
{
var method = frame.GetMethod();
if (method != null && method.ReflectedType.IsSubclassOf(typeof(BaseClass)))
fullnameArray.Add(method.ReflectedType.FullName);
}
catch { }
}
if (fullnameArray.Count() > 0)
{
return new PrincipalPermission(null, fullnameArray[0]);
}
return new PrincipalPermission(PermissionState.Unrestricted);
}
}
public class MyClassCalledFirstWork : BaseClass
{
public override void DoSomething()
{
Security.CreatePermission().Demand();
return;
}
}
public class MyClassCalledSecondDontWork : BaseClass
{
public override void DoSomething()
{
Security.CreatePermission().Demand();
return;
}
}