首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需求是:<PermissionSet class="System.Security.PermissionSet“version="1”Unrestricted="true"/>

需求是:<PermissionSet class="System.Security.PermissionSet“version="1”Unrestricted="true"/>
EN

Stack Overflow用户
提问于 2014-01-06 18:50:42
回答 1查看 3.5K关注 0票数 1

在尝试创建具有以下限制权限的System.Security.SecurityException The demand was for: <PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true"/>时,我将获得AppDomain:

代码语言:javascript
复制
var permissionSet = new PermissionSet(PermissionState.None);
    permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, System.Reflection.Assembly.GetExecutingAssembly().Location));
    permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
    permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));

这条错误消息告诉我,它将接受至少一个不受限制/完全信任的环境,但我不明白为什么需要这样做,也不知道如何修复它。

我只将Stub的一个实例创建到新的受限AppDomain中:

代码语言:javascript
复制
public interface IHostStub // Implemented by a MarshalByRefObject object in the primary AppDomain
{
    void Ping();
    void SayTime(DateTimeOffset time);
}

// In the restricted AppDomain
class Stub : MarshalByRefObject
{
    public event EventHandler OnQuit;

    public void RequestTime(IHostStub host)
    {    
        host.SayTime(DateTimeOffset.Now);
    }

    public void Quit(IHostStub host)
    {
        if (this.OnQuit != null) 
            this.OnQuit(this, new EventArgs());
    }
}

请你向我解释一下这条错误信息好吗?也许我误解了Unrestricted的意思。但是,将其设置为Unrestricted似乎使应用程序域自由支配(正如我预期的那样),而不考虑我添加或不添加到它的任何权限。

谢谢!

====

作为对@Nicole的回应,并在我完成这个过程中添加了一些发现,下面有两个代码示例。这是一个棘手的场景--沙箱插件--这需要太多的代码来显示所有的内容。第一个代码示例演示了异常。它有一个明显的修复,但它没有考虑到整个场景。

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly();

        var permissionSet = new PermissionSet(PermissionState.None);
        permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, currentAssembly.Location));
        permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
        permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));
        permissionSet.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));

        var appDomain = AppDomain.CreateDomain(
            "Sandboxed",
            null,
            new AppDomainSetup
            {
                ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
            },
            permissionSet,
            Assembly.GetExecutingAssembly().Evidence.GetHostEvidence<StrongName>());

        try
        {
            var stub = (Stub)appDomain.CreateInstanceFromAndUnwrap(
                currentAssembly.Location,
                typeof(Stub).FullName);
        }
        catch (SecurityException ex)
        {
            Console.WriteLine(ex);
            throw;
        }
    }
}

// In the restricted AppDomain
class Stub : MarshalByRefObject
{
}

在该示例中,ApplicationBase与主AppDomain相同。此外,程序集本身被列为AppDomain的AppDomain程序集。最简单的解决办法是删除这个完全信任的参数。

在下一个示例中,为了防止插件加载主机程序集,ApplicationBase被设置为一个甚至不需要存在的随机路径( PermissionState.Unrestricted可以很好地工作,如果目录确实存在的话,同样的错误)。AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;需要完全信任AFAIK,所以我必须列出具有完全信任的程序集(我认为它应该覆盖为该受信任程序集设置的对AppDomain的任何限制,而不是它可能加载的其他程序集)--这个程序集可以只是“加载器”,并且插件将是另一个程序集的一部分,对该程序集应该强制执行受限制的权限。我必须自定义AssemblyResolve,因为目录不存在(或者是空的),而且我想要控制加载其他程序集(例如,从byte[])。

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly();

        var permissionSet = new PermissionSet(PermissionState.None);
        permissionSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, currentAssembly.Location));
        permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
        permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));
        permissionSet.AddPermission(new ReflectionPermission(PermissionState.Unrestricted));

        string path;
        do
        {
            path = Path.GetTempPath() + Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
        } while (Directory.Exists(path));

        var appDomain = AppDomain.CreateDomain(
            "Sandboxed",
            null,
            new AppDomainSetup
            {
                ApplicationBase = path
            },
            permissionSet,
            Assembly.GetExecutingAssembly().Evidence.GetHostEvidence<StrongName>());

        try
        {
            var stub = (Stub)appDomain.CreateInstanceFromAndUnwrap(
                currentAssembly.Location,
                typeof(Stub).FullName);
        }
        catch (SecurityException ex)
        {
            Console.WriteLine(ex);
            throw;
        }
    }
}

class Stub : MarshalByRefObject
{
    static Stub()
    {
        AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;
    }

    public static Assembly AssemblyResolve(object sender, ResolveEventArgs e)
    {
        if (e.Name == Assembly.GetExecutingAssembly().FullName)
            return Assembly.GetExecutingAssembly();
        else
            Console.WriteLine("Unable to load {0}", e.Name);

        return null;
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-07 18:19:29

尝试通过Activator.CreateInstanceFrom而不是AppDomain.CreateInstanceFromAndUnwrap创建存根句柄。权限验证不同,使用Activator方法还可以避免向沙箱应用程序域添加额外的权限(除了SecurityPermission\Execution)。例如:

代码语言:javascript
复制
var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly();

var permissionSet = new PermissionSet(PermissionState.None);
permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));

var appDomain = AppDomain.CreateDomain(
    "Sandboxed",
    null,
    new AppDomainSetup { ApplicationBase = CreateFakePath() },
    permissionSet,
    currentAssembly.Evidence.GetHostEvidence<StrongName>());

var stub = (Stub)Activator.CreateInstanceFrom(appDomain, currentAssembly.Location, typeof(Stub).FullName).Unwrap();

var hostStub = new HostStub();
stub.RequestTime(hostStub);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20957089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档