如何从 DataAnnotations.ValidationAttribute 继承(它在 .NET 4 中的 Visual Studio 调试主机下显示 SecureCritical!

How to inherit from DataAnnotations.ValidationAttribute (it appears SecureCritical under Visual Studio debugging host in .NET 4 !)

提问人:codetuner 提问时间:4/22/2010 更新时间:7/30/2010 访问量:1401

问:

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

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

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

  1. ValidationAttribute 的子类位于 AllowPartiallyTrustedCallers 程序集中
  2. 反射用于检查属性
  3. 已启用 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(无需调试即可启动),一切正常,无一例外......

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

现在问题...

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

我能做些什么来解决这个问题?如何在 AllowPartiallyTrustedCallers 程序集中保留从 ValidationAttribute 继承的 MyValidationAttribute 而不将其标记为 SecurityCritical,仍然使用新的 .NET 4 级别 2 安全模型,并且仍然使用 VS.NET 调试主机(或其他主机)工作?

多谢! 鲁迪

安全性 net-4.0 代码访问安全

评论


答:

3赞 David DeWinter 5/31/2010 #1

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

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

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

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

我能做些什么来解决这个问题?如何在 AllowPartiallyTrustedCallers 程序集中保留从 ValidationAttribute 继承的 MyValidationAttribute 而不将其标记为 SecurityCritical,仍然使用新的 .NET 4 级别 2 安全模型,并且仍然使用 VS.NET 调试主机(或其他主机)使其工作?

这似乎是 VS 主机的错误,这对您的情况来说是不幸的。另一方面,你真的应该确保你希望你的程序集是 APTCA。如果有必要,那么您有几个选择。

  • 您可以将程序集保留原样。这是有利的,因为在最典型的部分信任环境中,ASP.NET,DataAnnotations 程序集将始终被视为 APTCA。当然,您将失去在 VS 托管过程中使用调试器的能力。
  • 您也可以标记您的组件 C-APTCA。你将能够在 VS 宿主进程中使用调试器,但程序集的使用 ASP.NET 需要将程序集添加到 web.config 中的 <partialTrustVisibleAssemblies> 元素,才能使其成为 APTCA。
  • 可以将属性设置为 SecurityCritical,这样就可以使用调试器,并且不需要在 ASP.NET 中进行任何特殊配置,但使用属性的所有类也必须是 Critical。
1赞 ZXX 7/14/2010 #2

出于某种原因,该网站将文本发布到一个与我写作时页面上的问题完全不同的问题中 - 奇怪。

评论

0赞 Sailing Judo 7/30/2010
IIS与任何事情有什么关系?这是一个控制台应用。