6

我有一个标有 的程序集,AllowPartiallyTrustedCallersAttribute其中包含一个自定义异常类。我想通过覆盖使其可序列化GetObjectData

随着 .NET 4,GetObjectData已经成为一种SecurityCritical方法。这意味着覆盖也需要是SecurityCritical. 由于我的程序集标有,因此除非另有说明,否则其中的AllowPartiallyTrustedCallersAttribute所有代码都是自动的。SecurityTransparent因此,我将 应用于SecurityCriticalAttributeGetObjectData 覆盖:

using System;
using System.Runtime.Serialization;
using System.Security;

[assembly:AllowPartiallyTrustedCallers]

namespace Library
{
  [Serializable]
  public class MyException : Exception
  {
    public string String;

    public MyException ()
    {
    }

    protected MyException (SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
      String = info.GetString ("String");
    }

    [SecurityCritical]
    public override void GetObjectData (System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
    {
      info.AddValue ("String", String);
      base.GetObjectData (info, context);
    }
  }
}

这在完全信任的情况下工作得很好,例如,当我从我的桌面运行链接这个程序集的代码时。

但是,当我从安全沙箱(见下文)使用此类时,我得到TypeLoadException

覆盖成员时违反了继承安全规则:'Library.MyException.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)'。重写方法的安全可访问性必须与被重写方法的安全可访问性相匹配。

我的问题:

  • 为什么我会收到此异常?我确实将覆盖标记为SecurityCritical,那么问题出在哪里?
  • 由于SecurityCriticalAttribute在我的沙箱中被忽略,此类在其他部分信任主机(例如 IIS/ASP.NET 或 SQL Server)中将如何表现?
  • 如何在 .NET 4 中实现可序列化的异常类?

沙盒代码:

var evidence = new Evidence();
evidence.AddHostEvidence (new Zone (SecurityZone.Internet));
var setupInfo = AppDomain.CurrentDomain.SetupInformation;
var permissionSet = SecurityManager.GetStandardSandbox (evidence);
permissionSet.AddPermission (new ReflectionPermission (ReflectionPermissionFlag.MemberAccess));
permissionSet.AddPermission (new SecurityPermission (SecurityPermissionFlag.ControlEvidence));
var sandbox = AppDomain.CreateDomain ("Sandbox", evidence, setupInfo, permissionSet);
4

3 回答 3

2

您已经自己回答了问题的第一部分。您的程序集被加载为安全透明,因为它没有以完全信任的方式加载,因此该SecurityCritical属性被忽略。所以你得到了例外。

而不是覆盖GetObjectData,您应该处理SerializeObjectState事件并创建一个实现ISafeSerializationData的类型来存储序列化的异常状态。这些存在于这个确切的场景中。

于 2017-10-26T22:25:01.710 回答
1

除了完全受信任的代码之外,您不能调用标有securitycritical属性的代码:

SecurityCriticalAttribute 相当于完全信任的链接需求。标有 SecurityCriticalAttribute 的类型或成员只能由完全受信任的代码调用;它不必要求特定的权限。它不能被部分受信任的代码调用。

这里有一个相关的问题,讨论了securitysafecriticalattribute的使用。

于 2013-01-02T16:08:39.817 回答
1

好吧,我知道这篇文章已经很老了,但是根据我最近的观察,如果您不在沙盒中提供程序集 FullTrust ,AppDomain则加载的程序集中的所有代码都将是安全透明的。这意味着SecurityCriticalAttribute应用于MyException.GetObjectData将什么都不做。它将是 SeurityTransparent,并且肯定与它的基本方法(即 SecurityCritical)不兼容。

希望这个提示会有所帮助。

请参阅https://docs.microsoft.com/en-us/dotnet/framework/misc/how-to-run-partially-trusted-code-in-a-sandbox,了解如何将沙盒中的某些程序集标记AppDomain为完全可信。

于 2017-09-01T16:02:50.690 回答