AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > .NET技术

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

51自学网 http://www.wanshiok.com
 

安全性和性能

.NET Framework 安全系统可以防止从网络上下载的恶意代码损坏您的计算机系统。但即使代码从不引发 SecurityException,这些安全检查也并不是没有代价的。

通常,公共语言运行库验证非托管方法的调用方在运行时是否对每个非托管方法调用都具有非托管代码访问权限。这对多次调用非托管代码的应用程序来说代价可能是非常高的。SuppressUnmanagedCodeSecurityAttribute 可以更改此默认行为。当用该属性声明非托管方法时,将在调用该方法的代码被加载到公共语言运行库中时检查安全请求。

安全说明   使用 SuppressUnmanagedCodeSecurityAttribute 时,应格外小心以确保没有引入安全漏洞。例如,开发人员需要验证用户正在安全使用非托管 API 以及调用方无法影响或滥用此调用。开发人员还可以添加适当的请求以确保所有调用方都具有适当的权限。例如,如果对本机代码进行调用以访问文件(目的是利用结构化存储,如扩展文件属性等),而非托管代码请求被禁止,则应明确发出一个文件 IO 请求以确保代码不会被误用。

示例 3:优化非托管调用

在本例中,对非托管代码权限的检查仅在加载时执行一次,而不是在每次调用非托管方法时都执行。如果多次调用非托管方法,则可能极大地提高性能。

// SuppressSecurity.csusing 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:    /* NOTE: The SuppressUnmanagedCodeSecurityAttribute disables the       check for the UnmanagedCode permission at runtime. Be Careful! */    [SuppressUnmanagedCodeSecurityAttribute()]    [DllImport("msvcrt.dll")]    internal static extern int puts(string str);    [SuppressUnmanagedCodeSecurityAttribute()]    [DllImport("msvcrt.dll")]    internal static extern int _flushall();}class MainClass{    // The security permission attached to this method will remove 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 method is attached with the Deny permission for    // unmanaged code, the permission gets overwritten. However, because    // you are using SuppressUnmanagedCodeSecurityAttribute here, you can    // still call the unmanaged methods successfully.    // The code should use other security checks to ensure that you don't    // incur a security hole.    [SecurityPermission(SecurityAction.Deny, Flags =        SecurityPermissionFlag.UnmanagedCode)]    private static void CallUnmanagedCodeWithoutPermission()    {        try        {            // The UnmanagedCode security check is disbled on the call            // below. However, the unmanaged call only displays UI. The             // security will be ensured by only allowing the unmanaged             // call if there is a UI permission.            UIPermission uiPermission =                new UIPermission(PermissionState.Unrestricted);            uiPermission.Demand();            Console.WriteLine("Attempting to call unmanaged code without UnmanagedCode permission.");            NativeMethods.puts("Hello World!");            NativeMethods._flushall();            Console.WriteLine("Called unmanaged code without UnmanagedCode permission.");        }        catch (SecurityException)        {            Console.WriteLine("Caught Security Exception attempting to call unmanaged code.");        }    }    // The security permission attached to this method will add the     // UnmanagedCode permission to the current set of permissions for the    // duration of the call to this method.    // 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.    // Because you are using SuppressUnmanagedCodeSecurityAttribute here,    // you can call the unmanaged methods successfully.    // The SuppressUnmanagedCodeSecurityAttribute will let you succeed,     // even if you don't have a permission.    [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. However, because you are using        // SuppressUnmanagedCodeSecurityAttribute, you can still call the       // unmanaged methods successfully.       // The code should use other security checks to ensure that you        // don't incur a security hole.       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. Because you are using       // SuppressUnmanagedCodeSecurityAttribute, you can call the       // unmanaged methods successfully.       // The SuppressUnmanagedCodeSecurityAttribute will let you succeed,       // even if you don't have a permission.       perm.Deny();       CallUnmanagedCodeWithPermission();    }}

输出

Attempting to call unmanaged code without UnmanagedCode permission.Hello World!Called unmanaged code without UnmanagedCode permission.Attempting to call unmanaged code with permission.Hello World!Called unmanaged code with permission.

代码讨论

请注意,以上示例允许两个非托管调用都成功,即使第一个调用不具有 UnmanagedCode 权限。在使用 SuppressUnmanagedCodeSecurityAttribute 时,应使用其他安全检查以确保不会招致安全漏洞。在上面的示例中,通过在非托管调用之前添加 UIPermissionDemand

uiPermission.Demand();

做到这一点,它确保调用方具有显示 UI 的权限。

 
 

上一篇:C# 程序员参考--线程处理教程  下一篇:C# 程序员参考--属性教程