Client authentication during a call to .NET remote work

Given this MarshalByRef class:

public class MyRemotedClass : MarshalByRef { public void DoThis() { ... } public void DoThat() { ... } } 

Client Code:

 MyRemotedClass m = GetSomehowMyRemotedClass(); m.DoThis(); m.DoThat(); 

I can have several clients doing the same thing at the same time. I would like to distinguish customers. How can I identify inside remote access methods that make a remote call call? For example, I could record who did what. (Actually, I don’t need to keep track of the true customer information, I just want to be able to group calls by customers.)

[Edited to add additional background information]

I have a huge amount of code to cover, including properties. Therefore, expanding the list of input parameters is not an option.

+7
multithreading remoting
source share
1 answer

One of the things you can do is identify the client by IP address by running IServerChannelSinkProvider .

Add this class to the remote host project:

ClientIPServerSinkProvider.cs

 using System; using System.Collections; using System.IO; using System.Runtime.Remoting; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Channels; using System.Threading; using System.Net; namespace MyRemotingEnvironment { public class ClientIPServerSinkProvider : IServerChannelSinkProvider { private IServerChannelSinkProvider _nextProvider = null; public ClientIPServerSinkProvider() { } public ClientIPServerSinkProvider( IDictionary properties, ICollection providerData) { } public IServerChannelSinkProvider Next { get { return _nextProvider; } set { _nextProvider = value; } } public IServerChannelSink CreateSink(IChannelReceiver channel) { IServerChannelSink nextSink = null; if (_nextProvider != null) { nextSink = _nextProvider.CreateSink(channel); } return new ClientIPServerSink(nextSink); } public void GetChannelData(IChannelDataStore channelData) { } } public class ClientIPServerSink : BaseChannelObjectWithProperties, IServerChannelSink, IChannelSinkBase { private IServerChannelSink _nextSink; public ClientIPServerSink(IServerChannelSink next) { _nextSink = next; } public IServerChannelSink NextChannelSink { get { return _nextSink; } set { _nextSink = value; } } public void AsyncProcessResponse( IServerResponseChannelSinkStack sinkStack, Object state, IMessage message, ITransportHeaders headers, Stream stream) { IPAddress ip = headers[CommonTransportKeys.IPAddress] as IPAddress; CallContext.SetData("ClientIPAddress", ip); sinkStack.AsyncProcessResponse(message, headers, stream); } public Stream GetResponseStream( IServerResponseChannelSinkStack sinkStack, Object state, IMessage message, ITransportHeaders headers) { return null; } public ServerProcessing ProcessMessage( IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { if (_nextSink != null) { IPAddress ip = requestHeaders[CommonTransportKeys.IPAddress] as IPAddress; CallContext.SetData("ClientIPAddress", ip); ServerProcessing spres = _nextSink.ProcessMessage( sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream); return spres; } else { responseMsg = null; responseHeaders = null; responseStream = null; return new ServerProcessing(); } } } } 

Then, when you start your remote host, do the following:

 BinaryServerFormatterSinkProvider bp = new BinaryServerFormatterSinkProvider(); ClientIPServerSinkProvider csp = new ClientIPServerSinkProvider(); csp.Next = bp; Hashtable ht = new Hashtable(); ht.Add("port", "1234"); // Your remoting port number TcpChannel channel = new TcpChannel(ht, null, csp); ChannelServices.RegisterChannel(channel, false); RemotingConfiguration.RegisterWellKnownServiceType( typeof(MyRemotedClass), "MyRemotedClass.rem", WellKnownObjectMode.SingleCall); 

In your method calls, you can access the client IP address by doing:

 public class MyRemotedClass : MarshalByref { public void DoThis() { string clientIP = CallContext.GetData("ClientIPAddress").ToString(); } } 
+15
source share

All Articles