沙盒异常 "Derived types must either match the security accessibility of the base type or be less accessible."

Sandbox exception "Derived types must either match the security accessibility of the base type or be less accessible."

当我尝试在沙盒应用程序域中启用代码访问安全性时出现以下错误。

类型违反的继承安全规则:'XXX'。派生类型必须与基类型的安全可访问性相匹配或更难访问。

这是我的资料: 插件程序集有一个 class 实现了在 sdk 程序集中定义的接口。插件程序集未签名。此外,插件程序集在 AssemblyInfo.cs 中有 [assembly: SecurityTransparent] 示例:

public Class Bar : AbstractBase
{
// This class implements an abstract method defined in the base class

}

AbstractBase 在 SDK 二进制文件中定义并已签名。此外,当我在执行程序集中创建域时,它被标记为受信任。

[SecuritySafeCritical] public 抽象 class AbstractBase : MarshalByRefObject, IDisposable { public 抽象无效 BaseMethod();

[SecurityCritical]
    [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.Infrastructure)]
    public override object InitializeLifetimeService()
    {
        var lease = (ILease)base.InitializeLifetimeService();
        if (lease != null && lease.CurrentState == LeaseState.Initial)
        {
            lease.InitialLeaseTime = TimeSpan.FromHours(1);
            lease.SponsorshipTimeout = TimeSpan.FromHours(1);
            lease.RenewOnCallTime = TimeSpan.FromHours(1);
        }

        return lease;
    }

    protected void MethodFoo()
    {
    ...
    }

    public virtual Foo FooItIs{get;set;}   // Foo is a class which is a MarshallByRefObject and is implemented in the executing assembly
}

这是我在 AssemblyInfo.cs SDK 二进制文件中尝试过的。

[assembly: AllowPartiallyTrustedCallers]
[assembly: SecurityRules(SecurityRuleSet.Level2, SkipVerificationInFullTrust = true)]
//[assembly: SecurityRules(SecurityRuleSet.Level1)]

最后是创建域并应用安全限制的执行程序集。我在调用 CreateInstanceAndUnWrap 时遇到异常。

private void CreateAppDomain()
    {
        AppDomainSetup domainSetup = new AppDomainSetup();
        domainSetup.ApplicationName = "Plugins";
        domainSetup.ApplicationBase = Section.Instance.BaseDirectory;
        domainSetup.ConfigurationFile = domainSetup.ApplicationName + ".config";
        PermissionSet domainPermissions = new PermissionSet(PermissionState.None);

        domainPermissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
        domainPermissions.AddPermission(new IsolatedStorageFilePermission(PermissionState.Unrestricted));
        domainPermissions.AddPermission(new FileIOPermission(PermissionState.Unrestricted));

        domainPermissions.AddPermission(new System.Net.WebPermission(PermissionState.Unrestricted));
        domainPermissions.AddPermission(new System.Net.Mail.SmtpPermission(PermissionState.Unrestricted));

        domainPermissions.AddPermission(new System.Configuration.ConfigurationPermission(PermissionState.Unrestricted));
        domainPermissions.AddPermission(new System.Data.SqlClient.SqlClientPermission(PermissionState.Unrestricted));

        StrongName plugins = typeof(AbstractBase).Assembly.Evidence.GetHostEvidence<StrongName>();
        this.appDomain = AppDomain.CreateDomain(domainSetup.ApplicationName, null,
            domainSetup, domainPermissions,
            plugins);
    }

这是我创建实例的方式:

action =
                        this.appDomain.CreateInstanceFromAndUnwrap(
                        Path.Combine(pluginProperties.AssemblyBaseDirectory, pluginProperties.AssemblyName),
                        className) as
                        AbstractBase;

我不确定我遗漏了什么,或者我的架构在代码访问安全性方面是否存在某种错误?感谢您的帮助!

编辑: 这是堆栈跟踪。我的 UT 做的事情和上面描述的完全一样

at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly 程序集,字符串名称,布尔 throwOnError,布尔 ignoreCase,ObjectHandleOnStack 类型) 在 System.Reflection.RuntimeAssembly.GetType(字符串名称,布尔值 throwOnError,布尔值 ignoreCase) 在 System.Activator.CreateInstanceFromInternal(String assemblyFile,String typeName,Boolean ignoreCase,BindingFlags bindingAttr,Binder binder,Object[] args,CultureInfo culture,Object[] activationAttributes,Evidence securityInfo) 在 System.AppDomain.CreateInstanceFrom(字符串程序集文件,字符串类型名称) 在 System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName) 在 System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName) 在 Microsoft.Windows.Infrastructure.MissionControl.Eventing.Agent.Tests.ActionProcessorTests.TestActionExecuted() 中 ActionProcessorTests.cs:第 196 行

好吧,这是一个旧的 post,但我在尝试解决同样的问题时偶然发现了它。问题是你用 SecuritySafeCritical 标记了整个 AbstractBase class,但是 Bar class,因为它是无符号的,所以必须是SecurityTransparent。不允许从 SecuritySafeCritical class 派生 SecurityTransparent class。

解决方案是从 AbstractBase class 中删除 [SecuritySafeCritical] 属性。因为您已将 antire 程序集标记为 AllowPartiallyTrustedCallers,所以 AbstractBase class 将默认为 SecurityTransparent,并且 AbstractBaseBar 将是透明的。

然后,当您需要访问 SecuritySafeCriticalSecurityCritical 函数时,您可以将 AbstractBase 中的单个函数标记为 SecuritySafeCritical .这将允许这些方法访问更受限制的 classes.