"请求失败"在部分受信任的AppDomain中调用WCF操作时

时间:2014-04-08 21:28:09

标签: c# .net wcf appdomain code-access-security

我有一个完全信任.Net 4.5应用程序,它创建一个部分信任AppDomain。我试图通过WCF命名管道与此域进行通信。

我已成功创建该服务并已连接到该服务。但是,当我尝试调用任何服务的方法时,我得到了这个非常有用的错误:

  

未处理的类型' System.Security.SecurityException'   发生在System.ServiceModel.Internals.dll

中      

其他信息:请求失败。

>   System.ServiceModel.Internals.dll!System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(uint error, uint bytesRead, System.Threading.NativeOverlapped* nativeOverlapped) + 0x75 bytes 
    mscorlib.dll!System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) + 0x6e bytes    
    [Native to Managed Transition]  
    [Appdomain Transition]  
    [Native to Managed Transition]  
    kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
    ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
    ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

这就是全部,没有InnerException。

由于callstack建议从受限制的AppDomain抛出异常。不出所料,如果我以完全信任的方式创建域,问题就会消失。

包含该服务的程序集在受限制的AppDomain中完全受信任(请参阅下面的代码)。它可以创建管道,所以当我尝试使用它时为什么会窒息?这是在接收服务请求时哄骗它声明其权限的问题吗?

完全信任代码:

var evidence = new Evidence(null, new EvidenceBase[] { new Zone(SecurityZone.Internet) });

var setup = new AppDomainSetup() { ApplicationBase = InstallDirectory.FullName };
setup.PrivateBinPath = String.Join(Path.PathSeparator.ToString(), "Episodes", "bin");

var permissions = new PermissionSet(null);
permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));

GameDomain = AppDomain.CreateDomain("Bulletin.Game", evidence, setup, permissions, 
    typeof(Shared.IBulletinGame).Assembly.Evidence.GetHostEvidence<StrongName>(),
    typeof(Bulletin.Game).Assembly.Evidence.GetHostEvidence<StrongName>()
    );

Activator.CreateInstanceFrom(GameDomain, Path.Combine(InstallDirectory.FullName, "bin", "Bulletin.dll"), "Bulletin.Game");

GameService = new ChannelFactory<Shared.IBulletinGame>(
    new NetNamedPipeBinding(),
    new EndpointAddress("net.pipe://localhost/Bulletin/Game")
    ).CreateChannel();

GameService.Test(); // throws exception

部分信任代码:

[assembly: AllowPartiallyTrustedCallers()]

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Game : Shared.IBulletinGame
{
    // The constructor completes successfully.
    [SecurityCritical]
    public Game()
    {
        Host = new ServiceHost(this);
        Host.AddServiceEndpoint(typeof(Shared.IBulletinGame), new NetNamedPipeBinding(), "net.pipe://localhost/Bulletin/Game");
        Host.Open();
    }

    // Control doesn't even reach this method when I try to remotely call it,
    // unless I give the AppDomain full trust.
    public void Test()
    {
        System.Diagnostics.Debugger.Break();
    }
}

1 个答案:

答案 0 :(得分:1)

我的答案是抛弃WCF并使用老式的MarshalByRefObject来实现我的界面。现在一切都很完美。

尽管MSDN文档中关于远程处理已经过时的可怕警告,但似乎它仍然是进程内通信的一个非常好的选择(有时是唯一的选择......)。 Judging from the amount it's used in the framework它也不会很快消失。