我有一个[AllowPartiallyTrustedCallers]类库,其中包含System.DataAnnotations.ValidationAttribute的子类型。该库用于WCF服务的契约(Contract)类型。
在.NET 2/3.5中,此功能正常。但是,从.NET 4.0开始,在Visual Studio调试器中运行服务的客户端会导致异常“继承类型违反了继承安全规则:'(我的ValidationAttribute的子类型)'。派生类型必须与基本类型的安全可访问性匹配或难以获得。” (System.TypeLoadException)
仅当满足以下所有条件时,才会出现该错误:
因此,基本上,在Visual Studio.NET 2010中:
。
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();
}
}
}
按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。如果有必要,那么您有两种选择。
关于security - 如何从DataAnnotations.ValidationAttribute继承(它在.NET 4中的Visual Studio调试主机下显示SecureCritical!),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2690291/