更新:2007 年 11 月
| TypeName | ReviewDenyAndPermitOnlyUsage | 
| CheckId | CA2107 | 
| 类别 | Microsoft.Security | 
| 是否重大更改 | 是 | 
原因
某方法包含指定 PermitOnly 或 Deny 安全操作的安全检查。
规则说明
使用 PermitOnly 方法 和 CodeAccessPermission.Deny 安全操作应仅由掌握高级 .NET Framework 安全性知识的人员使用。应当对使用这些安全操作的代码进行安全检查。
Deny 会更改为响应安全请求而发生的堆栈审核的默认行为。它允许您指定在拒绝方法的持续时间内不得授予的权限,而无论调用方在调用堆栈中实际具有何种权限。如果堆栈审核检测到由 Deny 保护的方法,且所请求权限包含在已拒绝权限中,则堆栈审核失败。PermitOnly 也会更改堆栈审核的默认行为。它允许代码仅指定那些能够被授予的权限,而无论调用方具有何种权限。如果堆栈审核检测到由 PermitOnly 保护的方法,且所请求的权限未包含在 PermitOnly 指定的权限中,则堆栈审核失败。
因为用途有限且行为难以捉摸,应认真评估依赖这些操作的代码是否存在安全漏洞。请考虑下列事项:
- 链接要求 不受 Deny 或 PermitOnly 影响。 
- 如果 Deny 或 PermitOnly 与导致堆栈审核的请求发生在同一堆栈框架中,则安全操作不产生任何影响。 
- 通常情况下,可通过多种方法指定用于构造基于路径的权限的值。对一种形式的路径的拒绝访问不会拒绝对所有形式的路径的访问。例如,如果文件共享 \\Server\Share 映射到网络驱动器 X:,则要拒绝对共享中文件的访问,必须拒绝 \\Server\Share\File、X:\File 和访问该文件的其他每个路径。 
- CodeAccessPermission.Assert 可在到达 Deny 或 PermitOnly 之前终止堆栈审核。 
- 如果 Deny 会产生影响,即调用方具有 Deny 所阻止的权限,则调用方可跳过 Deny 直接访问受保护资源。同样,如果调用方不具有被拒绝的权限,则即使不存在 Deny,堆栈审核也会失败。 
如何修复冲突
只要使用上述安全操作,就会导致冲突。若要修复冲突,请不要使用这些安全操作。
何时禁止显示警告
仅在完成安全检查后,才能禁止显示此规则发出的警告。
示例
下面的示例演示 Deny 的部分限制。
下面的库包含一个类,该类包含两个相同方法,二者的唯一区别是保护它们的安全请求不同。
using System.Security;
using System.Security.Permissions;
using System;
namespace SecurityRulesLibrary
{
   public  class SomeSecuredMethods
   {
      // Demand immediate caller has suitable permission
      // before revealing sensitive data.
      [EnvironmentPermissionAttribute(SecurityAction.LinkDemand,
          Read="COMPUTERNAME;USERNAME;USERDOMAIN")]
      public static void MethodProtectedByLinkDemand()
      {
         Console.Write("LinkDemand: ");
      }
      [EnvironmentPermissionAttribute(SecurityAction.Demand,
          Read="COMPUTERNAME;USERNAME;USERDOMAIN")]
      public static void MethodProtectedByDemand()
      {
         Console.Write("Demand: ");
      }
   }
}
下面的应用程序演示 Deny 对库中的受保护方法的影响。
using System.Security;
using System.Security.Permissions;
using System;
using SecurityRulesLibrary;
namespace TestSecurityLibrary
{
    // Violates rule: ReviewDenyAndPermitOnlyUsage.
   public class TestPermitAndDeny
   {
      public static void TestAssertAndDeny()
      {
         EnvironmentPermission envPermission = new EnvironmentPermission(
               EnvironmentPermissionAccess.Read,
               "COMPUTERNAME;USERNAME;USERDOMAIN");
         envPermission.Assert();
         try
         {
            SomeSecuredMethods.MethodProtectedByDemand();
            Console.WriteLine(
               "Caller's Deny has no effect on Demand " + 
               "with the asserted permission.");
            SomeSecuredMethods.MethodProtectedByLinkDemand();
            Console.WriteLine(
               "Caller's Deny has no effect on LinkDemand " + 
               "with the asserted permission.");
         }
         catch (SecurityException e)
         {
            Console.WriteLine(
               "Caller's Deny protected the library.{0}", e);
         }
      }
      public static void TestDenyAndLinkDemand()
      {
         try
         {
            SomeSecuredMethods.MethodProtectedByLinkDemand();
            Console.WriteLine(
               "Caller's Deny has no effect with " +
               "LinkDemand-protected code.");
         }
         catch (SecurityException e)
         {
            Console.WriteLine(
               "Caller's Deny protected the library.{0}",e);
         }
      }
      public static void Main()
      {
         EnvironmentPermission envPermission = new EnvironmentPermission(
            EnvironmentPermissionAccess.Read,
            "COMPUTERNAME;USERNAME;USERDOMAIN");
         envPermission.Deny();
         //Test Deny and Assert interaction for LinkDemands and Demands.
         TestAssertAndDeny();
         //Test Deny's effects on code in different stack frame. 
         TestDenyAndLinkDemand();
         //Test Deny's effect on code in same frame as deny.
         try
         {
            SomeSecuredMethods.MethodProtectedByLinkDemand();
            Console.WriteLine(
               "This Deny has no effect with LinkDemand-protected code.");
         }
         catch (SecurityException e)
         {
            Console.WriteLine("This Deny protected the library.{0}",e);
         }
      }
   }
}
该示例产生下面的输出。
Demand: Caller's Deny has no effect on Demand with the asserted permission.
LinkDemand: Caller's Deny has no effect on LinkDemand with the asserted permission.
LinkDemand: Caller's Deny has no effect with LinkDemand-protected code.
LinkDemand: This Deny has no effect with LinkDemand-protected code.
请参见
概念
参考
CodeAccessPermission.PermitOnly