在部分受信任的 AppDomain 中调用 WCF 操作时出现“请求失败”
Posted
技术标签:
【中文标题】在部分受信任的 AppDomain 中调用 WCF 操作时出现“请求失败”【英文标题】:"Request failed" when invoking a WCF operation in a partially-trusted AppDomain 【发布时间】:2014-04-08 21:28:09 【问题描述】:我有一个完全信任的 .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。
正如调用堆栈所暗示的,异常是从受限制的 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】:我的答案是放弃 WCF 并使用老式的MarshalByRefObject
来实现我的界面。现在一切正常。
尽管 MSDN 文档中有关远程处理已过时的可怕警告,但对于进程内通信来说,它似乎仍然是一个非常好的选择(有时是唯一的选择......)。 Judging from the amount it's used in the framework 它也不会很快消失。
【讨论】:
以上是关于在部分受信任的 AppDomain 中调用 WCF 操作时出现“请求失败”的主要内容,如果未能解决你的问题,请参考以下文章
在沙盒 Appdomain 中加载程序集 - SecurityException