我有一个完全信任.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();
}
}
答案 0 :(得分:1)
我的答案是抛弃WCF并使用老式的MarshalByRefObject
来实现我的界面。现在一切都很完美。
尽管MSDN文档中关于远程处理已经过时的可怕警告,但似乎它仍然是进程内通信的一个非常好的选择(有时是唯一的选择......)。 Judging from the amount it's used in the framework它也不会很快消失。