更新:2007 年 11 月
| TypeName | SecuredTypesShouldNotExposeFields | 
| CheckId | CA2112 | 
| 类别 | Microsoft.Security | 
| 是否重大更改 | 是 | 
原因
某公共类型或受保护类型包含公共字段并且受 链接要求 保护。
规则说明
如果代码可以访问受链接要求保护的类型的实例,则该代码不必满足此链接要求就可以访问该类型的字段。
如何修复冲突
要修复与该规则的冲突,请使字段成为非公共的并添加返回字段数据的公共属性或方法。对类型的 LinkDemand 安全检查保护对类型的属性和方法的访问。但是,代码访问安全不适用于字段。
何时禁止显示警告
为解决安全问题并获得良好的设计,您都应该通过使公共字段成为非公共字段来修复冲突。如果字段不保存应保持安全的信息并且您不依赖于该字段的内容,则可以禁止显示此规则发出的警告。
示例
下面的示例包含一个带有非安全字段的库类型 (SecuredTypeWithFields),一个可以创建库类型实例但错误地将实例传递给没有权限创建这些实例的类型的类型 (Distributor),以及可以读取实例字段的应用程序代码(即使没有保护类型安全的权限)。
下面的库代码与该规则冲突。
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
namespace SecurityRulesLibrary
{
   // This code requires immediate callers to have full trust.
   [System.Security.Permissions.PermissionSetAttribute(
       System.Security.Permissions.SecurityAction.LinkDemand, 
       Name="FullTrust")]
   public class SecuredTypeWithFields 
   {
      // Even though the type is secured, these fields are not.
      // Violates rule: SecuredTypesShouldNotExposeFields.
      public double xValue;
      public double yValue;
      public SecuredTypeWithFields (double x, double y) 
      {
         xValue = x;
         yValue = y;
         Console.WriteLine(
            "Creating an instance of SecuredTypeWithFields.");
      }
      public override string ToString()
      {
          return String.Format (
            "SecuredTypeWithFields {0} {1}", xValue, yValue);
      }
   }
}
由于存在保护受保护类型的链接要求,因此应用程序无法创建实例。下面的类使此应用程序能够获取受保护类型的实例。
using System;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
// This assembly executes with full trust. 
namespace SecurityRulesLibrary
{
   // This type creates and returns instances of the secured type.
   // The GetAnInstance method incorrectly gives the instance 
   // to a type that does not have the link demanded permission.
   public class Distributor
   {
      static SecuredTypeWithFields s = new SecuredTypeWithFields(22,33);
      public static SecuredTypeWithFields GetAnInstance ()
      {
            return s;
      }
      public static void DisplayCachedObject ()
      {
         Console.WriteLine(
            "Cached Object fields: {0}, {1}", s.xValue , s.yValue);
      }
   }
}
下面的应用程序阐释在没有权限访问受保护类型的方法的情况下,代码如何才能访问其字段。
using System;
using System.Security;
using System.Security.Permissions;
using SecurityRulesLibrary;
// This code executes with partial trust.
[assembly: System.Security.Permissions.PermissionSetAttribute(
   System.Security.Permissions.SecurityAction.RequestRefuse,
   Name = "FullTrust")]
namespace TestSecurityExamples
{
    public class TestLinkDemandOnField
    {
        [STAThread]
        public static void Main()
        {
            // Get an instance of the protected object.
            SecuredTypeWithFields secureType = Distributor.GetAnInstance();
            // Even though this type does not have full trust,
            // it can directly access the secured type's fields.
            Console.WriteLine(
               "Secured type fields: {0}, {1}",
               secureType.xValue,
               secureType.yValue);
            Console.WriteLine("Changing secured type's field...");
            secureType.xValue = 99;
            // Distributor must call ToString on the secured object.
            Distributor.DisplayCachedObject();
            // If the following line is uncommented, a security 
            // exception is thrown at JIT-compilation time because 
            // of the link demand for full trust that protects 
            // SecuredTypeWithFields.ToString().
            // Console.WriteLine("Secured type {0}",secureType.ToString());
        }
    }
}
该示例产生下面的输出。
Creating an instance of SecuredTypeWithFields.
Secured type fields: 22, 33
Changing secured type's field...
Cached Object fields: 99, 33