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() { /* Chính bản thân phương thức sẽ gọi security permission Deny cho unmanaged code, và sẽ ghi chồng lên Assert permission trong stack frame.*/ SecurityPermission perm = new SecurityPermission(SecurityPermissionFlag.Unmanage dCode); perm.Assert(); CallUnmanagedCodeWithoutPermission(); /* Chính phương thức sẽ gọi security permission Assert cho unmanaged code, và sẽ ghi chồng lên Deny permission trong stack frame.*/ perm.Deny(); CallUnmanagedCodeWithPermission(); } } Output 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. Ví dụ 2 // Declaratively: Sử dụng những thuộc tính an toàn của permission // DeclarativeSecurity.cs using System; using System.Security; using System.Security.Permissions; using System.Runtime.InteropServices; class NativeMethods { /* Gọi đến unmanaged code. Thi hành phương thức đòi hỏi UnmanagedCode security permission. Nếu không có permission, thì sẽ đưa ra một ngoại lệ SecurityException:*/ [DllImport("msvcrt.dll")] public static extern int puts(string str); [DllImport("msvcrt.dll")] internal static extern int _flushall(); } class MainClass { /*Security permission được gắn vào phương thức này sẽ từ chối permission của UnmanagedCode từ những thiết lập của những permission hiện tại trong khi lời gọi phương thức có hiệu lực, thậm chí khi phương thức CallUnmanagedCodeWithoutPermission được gọi từ stack frame đã sẵn sàng gọi quyền cho unmanaged code, thì ta vẫn không thể gọi cái mã này, bởi vì hàm này được gắn với Deny permission cho unmanaged code, permission được ghi chồng.*/ [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."); } } /*security permission được gắn vào phương thức này sẽ bắt buộc kiểm tra thực thi cho unmanaged code permission bất cứ khi nào phương thức được gọi. Nếut lời gọi không có unmanaged code permission, thì lời gọi sẽ tạo ra một Security Exception. Thậm chí khi phương thức CallUnmanagedCodeWithPermission được gọi từ một stack frame sẵn sàng gọi Deny cho unmanaged code, nó sẽ không ngăn chặn ta từ lời gọi. Bởi vì phương thức này được gắn với Assert permission cho unmanaged code, permission đã được ghi chồng.*/ [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.Unmanage dCode); /* Chính bản thân phương thức được gắn với security permission Deny cho unmanaged code sẽ ghi chồng lên Assert permission trong stack frame này.*/ perm.Assert(); CallUnmanagedCodeWithoutPermission(); /* Phương thức được gắn với security permission Assert cho unmanaged code sẽ ghi chồng lên Deny permission trong stack frame.*/ perm.Deny(); CallUnmanagedCodeWithPermission(); } } Output 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. Security and Performance Hệ thống bảo mật của bộ khung .NET có khả năng ngăn chặn những đoạn mã có tính chất gây nguy hiểm được tải xuống từ mạng nằm trong máy tính. Tuy nhiên những công việc kiểm tra an toàn này có thể không được thực hiện, thậm chí khi đoạn mã không bao giờ đưa ra một ngoại lệ an toàn bảo mật nào. Thông thường ngôn ngữ thi hành chung ( common language runtime ) sẽ xác minh lời gọi từ những đoạn mã của một phương thức không được quản lý, những phương thức này không có những đoạn mã quản lý truy cập permission. Điều này có thể sẽ gây rất nhiều khó khăn cho ứng dụng khi thực hiện những lời gọi những đoạn mã không được quản lý. SuppressUnmanagedCodeSecurityAttribute sẽ thay thế cho vần đề mặc định này. Khi một phương thức được gắn thuộc tính này ( SuppressUnmanagedCodeSecurityAttribute ), yêu cầu bảo vệ an toàn được kiểm tra khi mà chương trình thực hiện gọi phương thức được nạp vào trình điều khiển của common language runtime. Security Note Khi dùng SuppressUnmanagedCodeSecurityAttribute ta cần phải thận trọng hơn để đảm bảo rằng sẽ không có một lỗi an toàn nào trong chương trình của ta ( code ). Ví dụ 3: // SuppressSecurity.cs using System; using System.Security; using System.Security.Permissions; using System.Runtime.InteropServices; class NativeMethods { /* Gọi đến unmanaged code. Thi hành phương thức đòi hỏiUnmanagedCode security permission. Nếu không có permission này thì sẽ đưa ra SecurityException:*/ /* Chú ý: SuppressUnmanagedCodeSecurityAttribute không thể kiểm tra UnmanagedCode permission lúc thi hành ! */ [SuppressUnmanagedCodeSecurityAttribute()] [DllImport("msvcrt.dll")] internal static extern int puts(string str); [SuppressUnmanagedCodeSecurityAttribute()] [DllImport("msvcrt.dll")] internal static extern int _flushall(); } class MainClass { /* security permission được gắn vào phương thức này sẽ hủy UnmanagedCode permission từ những thết lập permissions cho khoảng thời gian gọi đến phương thức này. Dù là phương thức CallUnmanagedCodeWithoutPermission được gọi từ một stack frame sẵn sàng gọi Assert cho unmanaged code, ta vẫn không thể gọi cái mã này. Bởi vì phương thức này đã được gắn Deny permission cho unmanaged code, permission đâ được ghi chồng. Tuy nhiên do ta dùng SuppressUnmanagedCodeSecurityAttribute ở đây, ta vẫn có thể gọi unmanaged methods thành công. Cái mã này sẽ dùng chế độ kiểm tra an toàn khác để đẩm bảo ta không mắc phải lỗ hổng an toàn bảo mật.*/ [SecurityPermission(SecurityAction.Deny, Flags = SecurityPermissionFlag.UnmanagedCode)] private static void CallUnmanagedCodeWithoutPermission() { try { /* The UnmanagedCode security check is disbled on the call below. Tuy nhiên, lời gọi unmanaged chỉ hiển thị UI. Security sẽ được đảm bảo vì chỉ cho phép gọi nếu có một 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