【问题标题】:Sandbox exception "Derived types must either match the security accessibility of the base type or be less accessible."沙盒异常“派生类型必须与基类型的安全可访问性匹配或难以访问。”
【发布时间】:2015-06-08 05:12:16
【问题描述】:

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

类型违反了继承安全规则:“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 { 公共抽象 void 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
}

这是我在 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 程序集,字符串名称,布尔 throwOnError,布尔 ignoreCase,ObjectHandleOnStack 类型) 在 System.Reflection.RuntimeAssembly.GetType(字符串名称,布尔 throwOnError,布尔 ignoreCase) 在 System.Activator.CreateInstanceFromInternal(字符串 assemblyFile,字符串 typeName,布尔忽略大小写,BindingFlags bindingAttr,Binder binder,Object[] args,CultureInfo 文化,Object[] activationAttributes,证据 securityInfo) 在 System.AppDomain.CreateInstanceFrom(字符串 assemblyFile,字符串 typeName) 在 System.AppDomain.CreateInstanceFromAndUnwrap(字符串 assemblyName,字符串 typeName) 在 System.AppDomain.CreateInstanceFromAndUnwrap(字符串 assemblyName,字符串 typeName) 在 Microsoft.Windows.Infrastructure.MissionControl.Eventing.Agent.Tests.ActionProcessorTests.TestActionExecuted() 在 ActionProcessorTests.cs:第 196 行

【问题讨论】:

  • SecurityTransparent 类不能从SecuritySafeCritical 类继承。

标签: c# .net sandbox appdomain code-access-security


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 2014-09-18
    • 2018-07-14
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    相关资源
    最近更新 更多