本示例演示了如何通过权限类和权限属性来修改安全权限
// ImperativeSecurity.cs
using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;
class NativeMethods
{
// 这是对非托管代码的调用。执行此方法需要
// UnmanagedCode 安全权限。如果没有此权限,
// 则调用此方法的尝试将引发 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()
{
// 创建安全权限对象以描述
// UnmanagedCode 权限:
SecurityPermission perm =
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
// 拒绝当前权限集中的 UnmanagedCode。
// 在此方法返回之前,在此线程上调用的任何方法
// 都不允许访问非托管代码。
// 即使 CallUnmanagedCodeWithPermission 方法
// 是从已经为非托管代码调用了
// Assert 的堆栈帧调用的,也无法调用本机
// 代码。由于此处使用了 Deny,因此权限
// 被覆盖。
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()
{
// 创建安全权限对象来描述
// UnmanagedCode 权限:
SecurityPermission perm =
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
// 检查您是否具有访问非托管代码的权限。
// 如果您没有访问非托管代码的权限,则
// 此调用将引发 SecurityException。
// 即使 CallUnmanagedCodeWithPermission 方法
// 是从已经为非托管代码调用了 Assert 的堆栈帧调用的,
// 也不能调用本机
// 代码。由于此处使用了 Deny,因此权限被
// 覆盖。
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()
{
// 该方法本身将为非托管代码调用安全权限 Deny,
// 这会重写此堆栈帧中的 Assert
// 权限。
SecurityPermission perm = new
SecurityPermission(SecurityPermissionFlag.UnmanagedCode);
perm.Assert();
CallUnmanagedCodeWithoutPermission();
// 该方法本身将为非托管代码调用安全权限 Assert,
// 这会重写此堆栈帧中的 Deny
// 权限。
perm.Deny();
CallUnmanagedCodeWithPermission();
}
}
// DeclarativeSecurity.cs
using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;
class NativeMethods
{
// 这是对非托管代码的调用。执行此方法需要
// UnmanagedCode 安全权限。如果没有此权限,
// 则调用此方法的尝试将引发 SecurityException:
[DllImport("msvcrt.dll")]
public static extern int puts(string str);
[DllImport("msvcrt.dll")]
internal static extern int _flushall();
}
class MainClass
{
// 附加到此方法的安全权限在调用此方法
// 期间将拒绝当前权限集中的
// UnmanagedCode 权限:
// 即使 CallUnmanagedCodeWithoutPermission 方法是在
// 已经为非托管代码调用了 Assert 的堆栈帧中调用的,
// 也无法调用本机代码。
// 由于此函数附加了非托管代码的 Deny 权限,
// 因此相应的安全权限被覆盖。
[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.");
}
}
// 每当调用此方法时,附加到此方法的安全权限都强制
// 对非托管代码权限进行
// 运行时检查。如果调用方不具有非托管代码
// 的访问权限,则调用将产生安全异常。
// 即使 CallUnmanagedCodeWithPermission 方法是在
// 已经为非托管代码调用了
// Deny 的堆栈帧中调用的,也不会妨碍您调用
// 本机代码。由于此方法附加了非托管代码的 Assert
// 权限,因此相应的安全权限被覆盖。
[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);
// 此方法本身附加了非托管代码
// 的 Deny 安全权限,这会重写
// 此堆栈帧中的 Assert 权限。
perm.Assert();
CallUnmanagedCodeWithoutPermission();
// 此方法本身附加了非托管代码
// 的安全权限 Assert,这会重写
// 此堆栈帧中的 Deny 权限。
perm.Deny();
CallUnmanagedCodeWithPermission();
}
}
// SuppressSecurity.cs
using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;
class NativeMethods
{
// 这是对非托管代码的调用。执行此方法需要
// UnmanagedCode 安全权限。如果没有此权限,
// 则调用此方法的尝试将引发 SecurityException:
/* 注意:SuppressUnmanagedCodeSecurityAttribute 禁止
在运行时检查 UnmanagedCode 权限。一定要小心!*/
[SuppressUnmanagedCodeSecurityAttribute()]
[DllImport("msvcrt.dll")]
internal static extern int puts(string str);
[SuppressUnmanagedCodeSecurityAttribute()]
[DllImport("msvcrt.dll")]
internal static extern int _flushall();
}
class MainClass
{
// 附加到此方法的安全权限在
// 调用此方法期间将从当前权限集中移除
// UnmanagedCode 权限。
// 即使 CallUnmanagedCodeWithoutPermission 方法是
// 在已经为非托管代码调用了
// Assert 的堆栈帧中调用的,也无法调用本机代码。
// 由于此方法附加了非托管代码的 Deny 权限,
// 因此相应的安全权限被覆盖。但是,由于
// 此处使用的是 SuppressUnmanagedCodeSecurityAttribute,因此
// 仍可以成功调用非托管方法。
// 该代码应使用其他安全检查方法,以确保不会
// 出现安全漏洞。
[SecurityPermission(SecurityAction.Deny, Flags =
SecurityPermissionFlag.UnmanagedCode)]
private static void CallUnmanagedCodeWithoutPermission()
{
try
{
// UnmanagedCode 安全检查在下面的调用中
// 被禁用。但非托管调用仅显示用户界面。
// 如果存在用户界面权限,则通过只允许非托管
// 调用可以确保安全。
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.");
}
}
// 附加到此方法的安全权限在调用此方法
// 期间将 UnmanagedCode
// 权限添加到当前权限集中。
// 即使 CallUnmanagedCodeWithPermission 方法是
// 在已经为非托管代码调用了
// Deny 的堆栈帧中调用的,也不会妨碍您调用
// 本机代码。由于此方法附加了非托管代码的 Assert 权限,
// 因此相应的安全权限被覆盖。
// 由于此处使用的是 SuppressUnmanagedCodeSecurityAttribute,因此
// 可以成功调用非托管方法。
// 即使您没有权限,
// SuppressUnmanagedCodeSecurityAttribute 也会使操作成功。
[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);
// 该方法本身附加了非托管代码
// 的安全权限 Deny,这会重写
// 此堆栈帧中的 Assert 权限。但是,由于使用的是
// SuppressUnmanagedCodeSecurityAttribute,因此仍可以成功调用
// 非托管方法。
// 该代码应使用其他安全检查方法,以确保
// 不会出现安全漏洞。
perm.Assert();
CallUnmanagedCodeWithoutPermission();
// 该方法本身附加了非托管代码
// 的安全权限 Assert,这会重写
// 此堆栈帧中的 Deny 权限。由于此处使用的是
// SuppressUnmanagedCodeSecurityAttribute,因此可以成功调用
// 非托管方法。
// 即使您没有权限,
// SuppressUnmanagedCodeSecurityAttribute 也会使操作成功。
perm.Deny();
CallUnmanagedCodeWithPermission();
}
}
