沙盒异常“派生类型必须匹配基类型的安全可访问性,或者访问性较差”

本文关键字:访问 类型 安全 或者 基类 异常 派生 | 更新日期: 2023-09-27 17:54:00

当我试图在沙箱应用程序域中启用代码访问安全性时,我得到以下错误。

类型:'XXX'违反了继承安全规则。派生类型必须匹配基类型的安全可访问性,否则不可访问。

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

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

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

[SecuritySafeCritical]抽象类AbstractBase: MarshalByRefObject, IDisposable{

[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
}

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

[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做了与上面描述的完全相同的事情

在System.Reflection.RuntimeAssembly

。GetType(RuntimeAssembly汇编,字符串名称,Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack类型)在System.Reflection.RuntimeAssembly。GetType(String name, Boolean throwOnError, Boolean ignoreCase)在System.Activator。createinstancefromminternal (String assemblyFile, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder Binder, Object[] args, CultureInfo文化,Object[] activationAttributes, Evidence securityInfo)在System.AppDomain。CreateInstanceFrom(String assemblyFile, String typeName)在System.AppDomain。createinstancefrommandunwrap(字符串assemblyName,字符串typeName)在System.AppDomain。createinstancefrommandunwrap(字符串assemblyName,字符串typeName)在ActionProcessorTests.cs:第196行

沙盒异常“派生类型必须匹配基类型的安全可访问性,或者访问性较差”

好吧,这是一个老帖子,但我无意中发现它,而试图解决同样的问题。问题是您已经用SecuritySafeCritical标记了整个AbstractBase类,但是Bar类,因为它是无符号的,所以必须是SecurityTransparent。不允许从SecuritySafeCritical类派生出SecurityTransparent

解决方案是从AbstractBase类中删除[SecuritySafeCritical]属性。因为您已经将整个程序集标记为AllowPartiallyTrustedCallers,所以AbstractBase类将默认为SecurityTransparent,并且AbstractBaseBar都将是Transparent。 然后,当需要访问SecuritySafeCriticalSecurityCritical函数时,将AbstractBase内部的单个函数标记为SecuritySafeCritical