I have an assembly marked with the AllowPartiallyTrustedCallersAttribute
which contains a custom exception class. I want to make it serializable by overriding GetObjectData
.
With .NET 4, GetObjectData
has become a SecurityCritical
method. This means that overrides also need to be SecurityCritical
. Since my assembly is marked with the AllowPartiallyTrustedCallersAttribute
, all code within is automatically SecurityTransparent
unless specified otherwise. Therefore, I apply the SecurityCriticalAttribute
to the GetObjectData override:
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);
}
}
}
This works fine in full trust scenarios, e.g., when I run code linking this assembly from my desktop.
However, when I use this class from a security sandbox (see below), I'm getting a TypeLoadException
:
Inheritance security rules violated while overriding member:
'Library.MyException.GetObjectData(System.Runtime.Serialization.SerializationInfo,
System.Runtime.Serialization.StreamingContext)'. Security
accessibility of the overriding method must match the security
accessibility of the method being overriden.
My questions:
- Why am I getting this exception? I did mark the override to be
SecurityCritical
, so where's the problem?
- Since the
SecurityCriticalAttribute
is ignored in my sandbox, how will this class behave in other partial trust hosts, such as IIS/ASP.NET or SQL Server?
- How do I implement a serializable exception class in .NET 4?
Sandboxing Code:
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);