2010-03-30 4 views
19

Je ne peux pas utiliser un canal non sécurisé une fois qu'un canal sécurisé a déjà été enregistré. Le code ci-dessous ne fonctionne que si du côté client, le canal non sécurisé est enregistré auparavant.Mixage de canaux sécurisés et non sécurisés

Est-il possible de mélanger des canaux sécurisés et non sécurisés sans aucune contrainte sur la commande d'enregistrement?

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: Pas de changement avec .NET 4 et VS 2010.

+3

Vous dites que cela "ne fonctionne pas"; pourriez-vous clarifier ce qu'il fait? –

+0

@ M.Babcock Votre commentaire est sur une très vieille question, à utiliser qui n'a pas été pendant quelques mois. Just fyi –

+0

Je savais que c'était une question assez ancienne mais je me suis dit que c'était toujours pertinent car les modérateurs ne l'ont pas encore désactivé. N'hésitez pas à supprimer ma réponse si vous estimez qu'elle est inutile. –

Répondre

1

Ce qui est intéressant, question vintage, j'ai passé une semaine à essayer de résoudre ce problème, et a dû mettre en place un travail autour. Mais voici ce que j'ai découvert: la réponse est la plus probable: NON, VOUS NE POUVEZ PAS. Explication: .NET remoting ne vous permet pas de choisir le canal client à utiliser lors de la création d'un objet. Du côté du serveur, il faudrait évidemment que le canal écoute le port en question, mais du côté client, il utiliserait n'importe quel canal disponible ou en créerait un nouveau - bien que j'enregistre toujours le mien.

Il semble donc (je ne l'ai trouvé nulle part dans la documentation) que s'il y a un canal client sécurisé disponible, celui-là est utilisé. Ainsi, dans l'exemple de la question, l'objet distant est créé par rapport au canal sécurisé, mais il attend un canal non sécurisé - il échoue donc. En cas de création d'une connexion non sécurisée en premier lieu, cela fonctionne parce qu'au moment où l'objet distant est créé, il n'y a pas de canal client sécurisé, donc le canal client non sécurisé est utilisé.

DEPANNAGE:

  1. Créer un AppDomain distinct pour, par exemple, un canal sécurisé.
  2. Dans cet AppDomain, créez un objet client qui se connecterait à la sécurité.
  3. Utilisez votre AppDomain par défaut pour tous les canaux non sécurisés.