我有一个[AllowPartiallyTrustedCallers]类库,其中包含System.DataAnnotations.ValidationAttribute的子类型。该库用于WCF服务的契约(Contract)类型。

在.NET 2/3.5中,此功能正常。但是,从.NET 4.0开始,在Visual Studio调试器中运行服务的客户端会导致异常“继承类型违反了继承安全规则:'(我的ValidationAttribute的子类型)'。派生类型必须与基本类型的安全可访问性匹配或难以获得。” (System.TypeLoadException)

仅当满足以下所有条件时,才会出现该错误:

  • ValidationAttribute的子类位于AllowPartiallyTrustedCallers程序集
  • Reflection用于检查
  • 属性
  • 启用了Visual Studio托管过程(“项目属性”中的复选框,“调试”选项卡)

  • 因此,基本上,在Visual Studio.NET 2010中:
  • 创建一个新的控制台项目
  • 添加对“System.ComponentModel.DataAnnotations” 4.0.0.0的引用,
  • 编写以下代码:


  • using System;
    
    [assembly: System.Security.AllowPartiallyTrustedCallers()]
    
    namespace TestingVaidationAttributeSecurity
    {
        public class MyValidationAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute
        { }
    
        [MyValidation]
        public class FooBar
        { }
    
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("ValidationAttribute IsCritical: {0}",
                    typeof(System.ComponentModel.DataAnnotations.ValidationAttribute).IsSecurityCritical);
    
                FooBar fb = new FooBar();
                fb.GetType().GetCustomAttributes(true);
    
                Console.WriteLine("Press enter to end.");
                Console.ReadLine();
            }
        }
    }
    
  • 按F5键,您将获得异常!

  • 按Ctrl-F5(无需调试即可启动),一切正常,无一异常(exception)...

    奇怪的是,根据运行程序的方式(F5或Ctrl + F5),ValidationAttribute是否为安全关键。如上面代码中的Console.WriteLine所示。但是话又说回来,这似乎也发生在其他属性(和类型?)上。

    现在的问题...

    为什么从ValidationAttribute继承而不是从System.Attribute继承时有这种行为? (使用Reflector我没有在ValidationAttribute类或其程序集上找到特殊设置)

    我该怎么解决呢?我如何保持MyValidationAttribute从AllowPartiallyTrustedCallers程序集中的ValidationAttribute继承而没有将其标记为SecurityCritical,仍然使用新的.NET 4 2级安全模型,并且仍然可以使用VS.NET调试主机(或其他主机)工作?

    非常感谢!
    鲁迪

    最佳答案



    这是因为System.ComponentModel.DataAnnotations程序集是有条件的APTCA,即它标记有以下属性。

    [assembly: AllowPartiallyTrustedCallers(PartialTrustVisibilityLevel = PartialTrustVisibilityLevel.NotVisibleByDefault)]
    

    即使完全信任默认的AppDomain,有关Visual Studio启动主机进程的方式也会导致CLR不尊重此程序集上的APTCA。这意味着DataAnnotations程序集中的所有类型和方法都是SecurityCritical。由于安全透明类型(MyValidationAttribute)无法从安全关键类型(ValidationAttribute)继承,因此将引发此异常。



    看来这是VS主机的错误,这对您的情况来说是不幸的。另一方面,您应该真正确定要使程序集成为APTCA。如果有必要,那么您有两种选择。
  • 您可以将程序集保持原样。这是有利的,因为在最典型的部分信任环境ASP.NET中,DataAnnotations程序集将始终被视为APTCA。当然,您将失去在VS托管过程中使用调试器的能力。
  • 您也可以标记程序集C-APTCA。您将能够在VS托管过程中使用调试器,但是ASP.NET中程序集的使用者将需要将程序集添加到web.config中的元素中,以使其成为APTCA。
  • 您可以将属性设置为SecurityCritical,因此可以使用调试器,并且在ASP.NET中不需要任何特殊配置,但是使用该属性的所有类也必须很关键。
  • 关于security - 如何从DataAnnotations.ValidationAttribute继承(它在.NET 4中的Visual Studio调试主机下显示SecureCritical!),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2690291/

    10-13 02:20