7

我有一个 [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 类或其程序集中找到特殊设置)

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

非常感谢!鲁迪

4

2 回答 2

3

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

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

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

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

我能做些什么来解决这个问题?如何保持 MyValidationAttribute 从 AllowPartiallyTrustedCallers 程序集中的 ValidationAttribute 继承而不将其标记为 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 中进行任何特殊配置,但所有使用您的属性的类也必须是关键的。
于 2010-05-30T22:15:07.457 回答
1

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

于 2010-07-14T10:22:10.180 回答