混合安全&不安全的渠道

发布于 2024-08-27 06:32:19 字数 3294 浏览 4 评论 0原文

一旦注册了安全通道,我就无法使用不安全的通道。仅当在客户端之前注册了不安全通道时,以下代码才有效。

是否可以混合安全和不安全的通道而不对注册顺序有任何限制?

using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

public class SampleObject : MarshalByRefObject
{
    public DateTime GetTest() { return DateTime.Now; }
}
public class SampleObject2 : MarshalByRefObject
{
    public DateTime GetTest2() { return DateTime.Now; }
}
static class ProgramClient
{
    private static TcpClientChannel RegisterChannel(bool secure, string name, int priority)
    {
        IDictionary properties = new Hashtable();
        properties.Add("secure", secure);
        properties.Add("name", name);
        properties.Add("priority", priority);
        var clientChannel = new TcpClientChannel(properties, null);
        ChannelServices.RegisterChannel(clientChannel, false);
        return clientChannel;
    }
    private static void Secure()
    {
        RegisterChannel(true, "clientSecure", 2);
        var testSecure = (SampleObject2)Activator.GetObject(typeof(SampleObject2), "tcp://127.0.0.1:8081/Secured.rem");
        Console.WriteLine("secure: " + testSecure.GetTest2().ToLongTimeString());
    }
    private static void Unsecure()
    {
        RegisterChannel(false, "clientUnsecure", 1);
        var test = (SampleObject)Activator.GetObject(typeof(SampleObject), "tcp://127.0.0.1:8080/Unsecured.rem");
        Console.WriteLine("unsecure: " + test.GetTest().ToLongTimeString());
    }
    internal static void MainClient()
    {
        Console.Write("Press Enter to start.");
        Console.ReadLine();
        // Works only in this order
        Unsecure();
        Secure();
        Console.WriteLine("Press ENTER to end");
        Console.ReadLine();
    }
}
static class ProgramServer
{
    private static TcpServerChannel RegisterChannel(int port, bool secure, string name)
    {
        IDictionary properties = new Hashtable();
        properties.Add("port", port);
        properties.Add("secure", secure);
        properties.Add("name", name);
        //properties.Add("impersonate", false);
        var serverChannel = new TcpServerChannel(properties, null);
        ChannelServices.RegisterChannel(serverChannel, secure);
        return serverChannel;
    }
    private static void StartUnsecure()
    {
        RegisterChannel(8080, false, "unsecure");
        RemotingConfiguration.RegisterWellKnownServiceType(typeof(SampleObject), "Unsecured.rem", WellKnownObjectMode.Singleton);
    }
    private static void StartSecure()
    {
        RegisterChannel(8081, true, "secure");
        RemotingConfiguration.RegisterWellKnownServiceType(typeof(SampleObject2), "Secured.rem", WellKnownObjectMode.Singleton);
    }
    internal static void MainServer()
    {
        StartUnsecure();
        StartSecure();
        Console.WriteLine("Unsecure: 8080\n Secure: 8081");
        Console.WriteLine("Press the enter key to exit...");
        Console.ReadLine();
    }
}
class Program
{
    static void Main(string[] args)
    {
        if (args.Length == 1 && args[0] == "server")
            ProgramServer.MainServer();
        else
            ProgramClient.MainClient();
    }
}

编辑:.NET 4 和 VS 2010 没有变化。

I am unable to use an unsecure channel once a secure channel has already been registered. The code below works only if on the client side, the unsecured channel is registered before.

Is it possible to mix secure and unsecure channels without any constraint on the registration order ?

using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

public class SampleObject : MarshalByRefObject
{
    public DateTime GetTest() { return DateTime.Now; }
}
public class SampleObject2 : MarshalByRefObject
{
    public DateTime GetTest2() { return DateTime.Now; }
}
static class ProgramClient
{
    private static TcpClientChannel RegisterChannel(bool secure, string name, int priority)
    {
        IDictionary properties = new Hashtable();
        properties.Add("secure", secure);
        properties.Add("name", name);
        properties.Add("priority", priority);
        var clientChannel = new TcpClientChannel(properties, null);
        ChannelServices.RegisterChannel(clientChannel, false);
        return clientChannel;
    }
    private static void Secure()
    {
        RegisterChannel(true, "clientSecure", 2);
        var testSecure = (SampleObject2)Activator.GetObject(typeof(SampleObject2), "tcp://127.0.0.1:8081/Secured.rem");
        Console.WriteLine("secure: " + testSecure.GetTest2().ToLongTimeString());
    }
    private static void Unsecure()
    {
        RegisterChannel(false, "clientUnsecure", 1);
        var test = (SampleObject)Activator.GetObject(typeof(SampleObject), "tcp://127.0.0.1:8080/Unsecured.rem");
        Console.WriteLine("unsecure: " + test.GetTest().ToLongTimeString());
    }
    internal static void MainClient()
    {
        Console.Write("Press Enter to start.");
        Console.ReadLine();
        // Works only in this order
        Unsecure();
        Secure();
        Console.WriteLine("Press ENTER to end");
        Console.ReadLine();
    }
}
static class ProgramServer
{
    private static TcpServerChannel RegisterChannel(int port, bool secure, string name)
    {
        IDictionary properties = new Hashtable();
        properties.Add("port", port);
        properties.Add("secure", secure);
        properties.Add("name", name);
        //properties.Add("impersonate", false);
        var serverChannel = new TcpServerChannel(properties, null);
        ChannelServices.RegisterChannel(serverChannel, secure);
        return serverChannel;
    }
    private static void StartUnsecure()
    {
        RegisterChannel(8080, false, "unsecure");
        RemotingConfiguration.RegisterWellKnownServiceType(typeof(SampleObject), "Unsecured.rem", WellKnownObjectMode.Singleton);
    }
    private static void StartSecure()
    {
        RegisterChannel(8081, true, "secure");
        RemotingConfiguration.RegisterWellKnownServiceType(typeof(SampleObject2), "Secured.rem", WellKnownObjectMode.Singleton);
    }
    internal static void MainServer()
    {
        StartUnsecure();
        StartSecure();
        Console.WriteLine("Unsecure: 8080\n Secure: 8081");
        Console.WriteLine("Press the enter key to exit...");
        Console.ReadLine();
    }
}
class Program
{
    static void Main(string[] args)
    {
        if (args.Length == 1 && args[0] == "server")
            ProgramServer.MainServer();
        else
            ProgramClient.MainClient();
    }
}

Edit: No change with .NET 4 and VS 2010.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

转瞬即逝 2024-09-03 06:32:19

这是一个有趣的老式问题,我花了大约一周的时间试图解决这个问题,并且必须实施解决方法。但我发现:答案很可能是:不,你不能。

说明:.NET 远程处理不允许您在创建对象时选择要使用的客户端通道。显然,在服务器端,它会使用侦听相关端口的通道,但在客户端,它只会使用任何可用的端口,甚至创建一个新端口 - 尽管我总是注册自己的端口。

所以看来(我在文档中找不到它)如果有可用的安全客户端通道,就会使用该通道。因此,在问题的示例中,远程对象是针对安全通道创建的,但它期望不安全的通道 - 因此它失败了。如果首先创建不安全的连接 - 它会起作用,因为在创建远程对象时没有安全的客户端通道,因此使用不安全的客户端通道。

解决方法:

  1. 例如,为安全通道创建一个单独的 AppDomain。
  2. 在该 AppDomain 中,创建一个将连接到安全的客户端对象。
  3. 对所有不安全的通道使用默认的 AppDomain。

This is interesting vintage question, I have spent about a week trying to solve this problem, and had to implement a work-around. But here is what I have discovered: the answer is most likely: NO, YOU CANNOT.

Explanation: .NET remoting does not let you choose which client channel to use when creating an object. On the server side, it would use the channel listening to the port in question, obviously, but on the client side it would just use any available or even create a new one - though I always register my own.

So it seems (I could not find it anywhere in documentation) that if there is a secure client channel available, that one gets used. So in example in the question, the remote object is created against the secure channel, but it expects insecure one - thus it fails. In case of creating an insecure connection first - it works because at the time the remote object is created there is no secure client channel, so the insecure client channel is used.

WORKAROUND:

  1. Create a separate AppDomain for, for instance, secure channel.
  2. In that AppDomain, create a client object that would connect to the secure.
  3. Use your default AppDomain for all insecure channels.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文