【问题标题】:Assert Permissions in C#在 C# 中声明权限
【发布时间】:2012-02-27 05:32:23
【问题描述】:

我正忙于了解 c# 中的安全性内容,并且正在努力了解 Assert 的工作原理。我正在使用 .net 3.5。

我制作了一个示例应用程序来尝试解决这个问题。

调用方法:

[FileIOPermission(SecurityAction.Deny, ViewAndModify = @"C:\")]
    static void Main(string[] args)
    {
        WriteTest testWriter = new WriteTest();
        testWriter.Test();
        Console.Read();
    }

在一个单独的类库中我有:

public class WriteTest
{
    public void Test()
    {
        try
        {
            FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Write, @"C:\");
            permission.Assert();
            using (StreamWriter sw = new StreamWriter(@"C:\test.txt"))
            {
                sw.WriteLine("testing!");
                sw.Flush();
            }
            Console.WriteLine("Writen to file!");
        }
        catch (SecurityException sec)
        {
            Console.WriteLine("No privileges!");
        }
    }
}

这段代码执行得很好。它将写入文件。我的问题是这到底是如何工作的?如果我可以断言我想要的权限以便它跳过检查,这不会使安全类无效吗?如果我将 Assert 更改为 Demand,则会引发异常。

安全类的重点是不允许我设置权限,以便当我调用第三方类时,我可以防止它变得流氓并做我不希望它做的事情?我知道如果我将 dll 加载到 AppDomain 中,即使第三方 DLL 确实使用 Assert,我也会得到这种效果,但如果我直接调用它会起作用,这似乎很奇怪。我已尝试阅读有关 Assert 的 MSDN 文档,但我发现它很难理解。

【问题讨论】:

  • 确保您需要了解 .NET 4 之前的安全模型...因为 .NET 4.0 代码访问安全性已被简化。

标签: c# .net permissions code-access-security


【解决方案1】:

Assert()less 特权代码(“程序集 A”)调用 更多 特权代码(“程序集 B”)来执行某些任务时很有用。要执行该任务,程序集 B 需要运行需要强大权限的代码——程序集 A 可能没有的权限。所以大会 B 首先要求一个不太强大的权限(首先执行任务的权限),然后断言更强大的权限来实际执行任务。

例如,假设一个部分信任的 Silverlight 应用程序想要使用 System.Net.WebRequest 类发出 HTTP 请求。建立网络连接需要SocketPermission,但这是一个强大的低级权限,不应授予来自 Internet 的不受信任的代码。所以WebRequest 需要一个不太强大的权限,WebPermission,然后在继续建立网络连接之前断言SocketPermission

现在,在您的特定示例中,Assert() 覆盖了Deny,因为类库以与应用程序相同的特权级别运行 - 应用程序和类库都可能正在运行作为完全信任。程序集始终可以Assert() 其授权集中的任何权限。要在类库上强制使用Deny,您必须将类库放在沙箱中。

注意:在 .NET 4.0 中,Deny 已被弃用。来自MSDN Library

已删除用于执行 Deny、RequestMinimum、RequestOptional 和 RequestRefuse 权限请求的运行时支持。一般来说,这些请求没有得到很好的理解,并且在使用不当时可能会出现安全漏洞:

  • 拒绝操作很容易被断言操作覆盖。如果权限在程序集的授权集中,则程序集中的代码能够对权限执行 Assert 操作。 Assert 阻止了 Deny 在堆栈上的显示,使其无效。

【讨论】:

  • 谢谢!这有助于理解这一切
【解决方案2】:

Assert() 方法导致代码访问安全 (CAS) 停止在特定权限检查请求上遍历堆栈。

Assert 是一个可以在代码访问权限上调用的方法 类和 PermissionSet 类。您可以使用 Assert 来启用 您的代码(和下游调用者)执行您的代码所执行的操作 有权限做,但它的调用者可能没有权限做。 安全断言改变了运行时的正常进程 在安全检查期间执行。当你声明一个权限时,它 告诉安全系统不要检查代码的调用者 声明的权限。

Using the Assert Method

我想你想要Demand()

感兴趣的:

【讨论】:

  • 我确实理解它的作用,但我只是对它为什么这样做感到困惑。在我看来,Assert 只是否定了调用者设置的权限,这使得设置权限对我来说似乎毫无意义。如果我导入一些第三方dll并将其设置为没有写入权限(就像我在这里所做的那样),第三方dll可以使用Assert并获得写入权限吗?
  • @DavidEsteves 断言仅适用于在程序集级别已经具有写入权限的 DLL(例如,它们在 AppDomain 的完全信任程序集列表中)。简而言之,这意味着“用我的程序集级权限覆盖堆栈级权限”。
  • 我们有 SecurityPermissionFlag.Assertion 的枚举(用于 SecurityPermission 类),可以在新 Appdomain 的调用者中设置。它可以防止第三方程序集断言吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2016-05-28
  • 2019-06-21
  • 2014-11-28
  • 2018-08-05
  • 1970-01-01
相关资源
最近更新 更多