C# 程序员参考--安全性教程

发表于:2007-06-21来源:作者:点击数: 标签:
下一页 1 2 本教程讨论了 .NET Framework 安全性并显示了在 C# 修改安全权限的两种方式:命令性安全和声明性安全。 教程 大多数应用程序和组件 开发 人员不需完成任何特别的工作就可使用 .NET Framework 安全系统并从它所提供的安全保护中受益。 但“安全库

下一页 1 2 

   

本教程讨论了 .NET Framework 安全性并显示了在 C# 修改安全权限的两种方式:命令性安全和声明性安全。

教程

大多数应用程序和组件开发人员不需完成任何特别的工作就可使用 .NET Framework 安全系统并从它所提供的安全保护中受益。

但“安全库”是一个例外,它要求了解更多深入的知识并对安全系统加以特殊考虑。这些代码表明了安全托管代码与非限制代码之间的界限,后者如本机代码(这超出了 .NET Framework 安全基础结构可以强制的范围)。这些库通常必须受到高度信任才可以工作,它们是托管代码中编程错误会潜在地暴露安全隐患的一个位置。代码访问安全性无法消除人为错误的可能性,但相对于使用几个安全库的大量应用程序代码而言,需要严格审查的代码量将大大减少。

示例

该教程包括下列示例:

  • 示例 1:强制式安全性
  • 示例 2:声明式安全性
  • 示例 3:禁止安全性

安全性

.NET Framework 安全性通过在托管代码上强制实施安全限制来防止其他代码误用或破坏您的代码和数据。当 .NET Framework 应用程序请求权限时,由管理员建立的安全策略将授予权限或拒绝运行代码。信任是基于有关代码的证据(如数字签名、代码来自何处等)的。一旦授予权限,安全性就会实施控制这些代码可以做什么(或如果未授予权限,则控制代码不能做什么)的权限。

权限

.NET Framework 安全性只有当代码具有使用受保护资源的“权限”时才允许它使用这些资源。为了表示此情形,.NET Framework 使用了“权限”的概念,它表示代码访问受保护资源的权力。代码请求所需的权限,然后由 .NET Framework 应用的安全策略确定实际授予代码哪些权限。

.NET Framework 提供了代码访问权限类,其中每个类都封装了访问某一特定资源的能力。使用这些权限向 .NET Framework 指示需要允许代码做什么以及必须授权代码的调用方做什么。策略还使用这些对象确定要向代码授予哪些权限。

策略

安全策略的强制性保证了 .NET Framework 托管代码的安全。每个加载的程序集都受到安全策略的约束,安全策略基于信任授予代码权限,而信任又是基于有关代码的证据的。有关管理安全策略的信息,请参见“阅读材料列表”中的 .NET Framework 文档。

在 C# 中请求安全权限

在 C# 中请求安全权限的方法有以下两种:

  • 强制式:使用对 .NET Framework 中权限类的调用
  • 声明式:使用安全权限属性

下面两个示例说明了这两种方法。有关请求安全权限的更多信息,请参见要求

示例 1:强制式安全性

以下示例使用 .NET Framework 调用拒绝 UnmanagedCode 权限。

// ImperativeSecurity.cs
using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;

class NativeMethods
{
    // This is a call to unmanaged code. Executing this method requires 
    // the UnmanagedCode security permission. Without this permission
    // an attempt to call this method will throw a SecurityException:
    [DllImport("msvcrt.dll")]
    public static extern int puts(string str);
    [DllImport("msvcrt.dll")]
    internal static extern int _flushall();
}

class MainClass
{
    private static void CallUnmanagedCodeWithoutPermission()
    {
        // Create a security permission object to describe the
        // UnmanagedCode permission:
        SecurityPermission perm = 
           new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);

        // Deny the UnmanagedCode from our current set of permissions.
        // Any method that is called on this thread until this method 
        // returns will be denied aclearcase/" target="_blank" >ccess to unmanaged code.
        // Even though the CallUnmanagedCodeWithPermission method
        // is called from a stack frame that already
        // calls Assert for unmanaged code, you still cannot call native
        // code. Because you use Deny here, the permission gets 
        // overwritten.
        perm.Deny();

        try
        {
            Console.WriteLine("Attempting to call unmanaged code without permission.");
            NativeMethods.puts("Hello World!");
            NativeMethods._flushall();
            Console.WriteLine("Called unmanaged code without permission. Whoops!");
        }
        catch (SecurityException)
        {
            Console.WriteLine("Caught Security Exception attempting to call unmanaged code.");
        }
    }

    private static void CallUnmanagedCodeWithPermission()
    {
        // Create a security permission object to describe the
        // UnmanagedCode permission:
        SecurityPermission perm = 
           new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);

        // Check that you have permission to access unmanaged code.
        // If you don't have permission to access unmanaged code, then
        // this call will throw a SecurityException.
        // Even though the CallUnmanagedCodeWithPermission method
        // is called from a stack frame that already
        // calls Assert for unmanaged code, you still cannot call native
        // code. Because you use Deny here, the permission gets 
        // overwritten.
        perm.Assert();

        try
        {
            Console.WriteLine("Attempting to call unmanaged code with permission.");
            NativeMethods.puts("Hello World!");
            NativeMethods._flushall();
            Console.WriteLine("Called unmanaged code with permission.");
        }
        catch (SecurityException)
        {
            Console.WriteLine("Caught Security Exception attempting to call unmanaged code. Whoops!");
        }
    }

    public static void Main() 
    {
        // The method itself will call the security permission Deny 
        // for unmanaged code, which will override the Assert permission
        // in this stack frame.
        SecurityPermission perm = new 
            SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
        perm.Assert();
        CallUnmanagedCodeWithoutPermission();

        // The method itself will call the security permission Assert
        // for unmanaged code, which will override the Deny permission in
        // this stack frame.
        perm.Deny();
        CallUnmanagedCodeWithPermission();
    }
}

输出

Attempting to call unmanaged code without permission.
Caught Security Exception attempting to call unmanaged code.
Attempting to call unmanaged code with permission.
Hello World!
Called unmanaged code with permission.

示例 2:声明式安全性

这是使用安全权限属性的同一个示例。

// DeclarativeSecurity.cs
using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;

class NativeMethods
{
    // This is a call to unmanaged code. Executing this method requires 
    // the UnmanagedCode security permission. Without this permission,
    // an attempt to call this method will throw a SecurityException:
    [DllImport("msvcrt.dll")]
    public static extern int puts(string str);
    [DllImport("msvcrt.dll")]
    internal static extern int _flushall();
}

class MainClass
{
    // The security permission attached to this method will deny the
    // UnmanagedCode permission from the current set of permissions for
    // the duration of the call to this method:
    // Even though the CallUnmanagedCodeWithoutPermission method is
    // called from a stack frame that already calls
    // Assert for unmanaged code, you still cannot call native code.
    // Because this function is attached with the Deny permission for
    // unmanaged code, the permission gets overwritten.
    [SecurityPermission(SecurityAction.Deny, Flags = 
       SecurityPermissionFlag.UnmanagedCode)]
    private static void CallUnmanagedCodeWithoutPermission()
    {
        try
        {
            Console.WriteLine("Attempting to call unmanaged code without permission.");
            NativeMethods.puts("Hello World!");
            NativeMethods._flushall();
            Console.WriteLine("Called unmanaged code without permission. Whoops!");
        }
        catch (SecurityException)
        {
            Console.WriteLine("Caught Security Exception attempting to call unmanaged code.");
        }
    }

    // The security permission attached to this method will force a 
    // runtime check for the unmanaged code permission whenever
    // this method is called. If the caller does not have unmanaged code
    // permission, then the call will generate a Security Exception.
    // Even though the CallUnmanagedCodeWithPermission method is called
    // from a stack frame that already calls
    // Deny for unmanaged code, it will not prevent you from calling
    // native code. Because this method is attached with the Assert
    // permission for unmanaged code, the permission gets overwritten.
    [SecurityPermission(SecurityAction.Assert, Flags = 
       SecurityPermissionFlag.UnmanagedCode)]
    private static void CallUnmanagedCodeWithPermission()
    {
        try
        {
            Console.WriteLine("Attempting to call unmanaged code with permission.");
            NativeMethods.puts("Hello World!");
            NativeMethods._flushall();
            Console.WriteLine("Called unmanaged code with permission.");
        }
        catch (SecurityException)
        {
            Console.WriteLine("Caught Security Exception attempting to call unmanaged code. Whoops!");
        }
    }

    public static void Main() 
    {
        SecurityPermission perm = new
            SecurityPermission(SecurityPermissionFlag.UnmanagedCode);

        // The method itself is attached with the security permission 
        // Deny for unmanaged code, which will override
        // the Assert permission in this stack frame.
        perm.Assert();
        CallUnmanagedCodeWithoutPermission();

        // The method itself is attached with the security permission
        // Assert for unmanaged code, which will override the Deny 
        // permission in this stack frame.
        perm.Deny();
        CallUnmanagedCodeWithPermission();
    }
}

输出

Attempting to call unmanaged code without permission.
Caught Security Exception attempting to call unmanaged code.
Attempting to call unmanaged code with permission.
Hello World!
Called unmanaged code with permission.

原文转自:http://www.ltesting.net