为什么没有加载Custom SecurityPermission?

mai*_*nmm 7 .net c# security reflection

我创建了一个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);
    }
}
Run Code Online (Sandbox Code Playgroud)

和用法

public class MyClassCalledFirstWork: BaseClass
{
    [MyPrincipalPermission(SecurityAction.Demand)]
    public override void DoSomething()
    {
        return;
    }
}

public class MyClassCalledSecondDontWork: BaseClass
{
    [MyPrincipalPermission(SecurityAction.Demand)]
    public override void DoSomething()
    {
        return;
    }
}
Run Code Online (Sandbox Code Playgroud)

Mac*_*ski 1

这是来自SecurityAttribute.CreatePermission () 的文档

“CreatePermission 方法创建一个权限对象,然后可以将其序列化为二进制形式,并与 SecurityAction 一起永久存储在程序集的元数据中。”

“在编译时,属性将安全声明转换为元数据中的序列化形式。元数据中的声明性安全数据是根据此方法返回的与此属性相对应的权限创建的。”

看起来只能有一个权限对象(某种类型)与为特定 SecurityAction 存储的自定义 CodeAccessSecurityAttribute 相对应。当您检查 DoSomething 方法的 IL 时,您可以看到它们包含与第一次 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
Run Code Online (Sandbox Code Playgroud)

评论中第二个问题的答案是:
我不会使用声明式 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;
    }
}
Run Code Online (Sandbox Code Playgroud)