Remoting and events
-
Even just a nudge in the right direction would be much appreciated... I'm trying to use events with remoting over a tcp channel (writing in C#, mostly), and I'm getting this Security Exception thrown: "System.Security.SecurityException: Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this level." I'm running this under an administrative account, and so far all the code is running locally on the machine. From what I've learned so far about security, I thought that all local code was defaulted full-trust permissions, so I'm not sure what the problem is. I've looked at several articles in various places, but most seem like just a general introduction to .net security. Any help would be greatly appreciated.
-
Even just a nudge in the right direction would be much appreciated... I'm trying to use events with remoting over a tcp channel (writing in C#, mostly), and I'm getting this Security Exception thrown: "System.Security.SecurityException: Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this level." I'm running this under an administrative account, and so far all the code is running locally on the machine. From what I've learned so far about security, I thought that all local code was defaulted full-trust permissions, so I'm not sure what the problem is. I've looked at several articles in various places, but most seem like just a general introduction to .net security. Any help would be greatly appreciated.
bwilhite wrote:
Even just a nudge in the right direction would be much appreciated...
I just wouldn't do it, period. The idea of an event is nothing more than an async message sent by the server to the client, i.e., not in direct response to a request, but in response to an event on the remote host side of the client server architecture. However the complications added by network protocols and security by attempting to use something as integrated as .NET events just seems like a bad idea. It is possible you have chosen an inappropriate approach given your requirements. Eventing is reliable in case of named pipe scenarios on same machine but not over network. So if underlying sockets close connection eventing won’t try to establish it for you. Using events over network is not recommended. But if you still want to use it, this post takes us over a simple client server example No mention of security issues but it might help somehow: http://blogs.msdn.com/dotnetremoting/archive/2006/04/07/571020.aspx[^]
led mike
-
bwilhite wrote:
Even just a nudge in the right direction would be much appreciated...
I just wouldn't do it, period. The idea of an event is nothing more than an async message sent by the server to the client, i.e., not in direct response to a request, but in response to an event on the remote host side of the client server architecture. However the complications added by network protocols and security by attempting to use something as integrated as .NET events just seems like a bad idea. It is possible you have chosen an inappropriate approach given your requirements. Eventing is reliable in case of named pipe scenarios on same machine but not over network. So if underlying sockets close connection eventing won’t try to establish it for you. Using events over network is not recommended. But if you still want to use it, this post takes us over a simple client server example No mention of security issues but it might help somehow: http://blogs.msdn.com/dotnetremoting/archive/2006/04/07/571020.aspx[^]
led mike
Thanks that gets me going in the right direction. As far as not doing it at all...this is experimental at this stage, but the only other real option would be our own full-fledged remote proxy. The concept of an event is the right one here... From what I can tell, we'd be duplicating *a lot* of the work done already by .net remoting...but like I said still experimental, and not sure which way we might go anyway. Incidentally, using a callback mechanism caused a similar security problem.
-
Even just a nudge in the right direction would be much appreciated... I'm trying to use events with remoting over a tcp channel (writing in C#, mostly), and I'm getting this Security Exception thrown: "System.Security.SecurityException: Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this level." I'm running this under an administrative account, and so far all the code is running locally on the machine. From what I've learned so far about security, I thought that all local code was defaulted full-trust permissions, so I'm not sure what the problem is. I've looked at several articles in various places, but most seem like just a general introduction to .net security. Any help would be greatly appreciated.
-
Even just a nudge in the right direction would be much appreciated... I'm trying to use events with remoting over a tcp channel (writing in C#, mostly), and I'm getting this Security Exception thrown: "System.Security.SecurityException: Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this level." I'm running this under an administrative account, and so far all the code is running locally on the machine. From what I've learned so far about security, I thought that all local code was defaulted full-trust permissions, so I'm not sure what the problem is. I've looked at several articles in various places, but most seem like just a general introduction to .net security. Any help would be greatly appreciated.
hi there, i had the same problem once, my solution: first, you have to supply some sinkproviders to your tcpchannel before marshalling your remoting object:
BinaryServerFormatterSinkProvider serverprovider = new BinaryServerFormatterSinkProvider(); BinaryClientFormatterSinkProvider clientprovider = new BinaryClientFormatterSinkProvider(); serverprovider.TypeFilterLevel = TypeFilterLevel.Full; IDictionary properties = new Hashtable(); properties["port"] = 9876; //your port TcpChannel chan = new TcpChannel(properties, clientprovider, serverprovider); /* ... Register channel and marshal your object ... */
then you have to add some stuff to your shared assembly (where you share intefaces between server & clients) add your event to the interfacepublic interface IMyServiceInterface { event System.EventHandler MyEvent; }
i also added a CustomEventArgs class to my shared assembly (System.EventArgs wasn't sufficient for my application, but you could just use EventArgs if you don't need to supply some custom information to your Eventhandler) then (maybe the most important thing) add an eventwrapper to your shared assembly:[Serializable] public class MyEventWrapper: MarshalByRefObject { public event EventHandler OnWrapperMessage; public void WrapperMessagehandler(object sender,CustomEventArgs e) { if(OnWrapperMessage!=null) { OnWrapperMessage(sender, e); } } public override object InitializeLifetimeService() { return null; //that your object doesn't expire } }
now you can use the event in your client the following way:IMyServiceInterface service = //.. use Activator to retrieve your remoting service; MyEventWrapper w = new MyEventWrapper(); service.OnLogData += w.WrapperMessagehandler; w.OnWrapperMessage += handler_formyevent; ... void handler_formyevent(object sender, CustomEventArgs e) { // .. do something }
maybe it looks a little bit complicating but that was how i managed the problem that you cannot use events in a normal way over remoting channels. i hope this helps -
hi there, i had the same problem once, my solution: first, you have to supply some sinkproviders to your tcpchannel before marshalling your remoting object:
BinaryServerFormatterSinkProvider serverprovider = new BinaryServerFormatterSinkProvider(); BinaryClientFormatterSinkProvider clientprovider = new BinaryClientFormatterSinkProvider(); serverprovider.TypeFilterLevel = TypeFilterLevel.Full; IDictionary properties = new Hashtable(); properties["port"] = 9876; //your port TcpChannel chan = new TcpChannel(properties, clientprovider, serverprovider); /* ... Register channel and marshal your object ... */
then you have to add some stuff to your shared assembly (where you share intefaces between server & clients) add your event to the interfacepublic interface IMyServiceInterface { event System.EventHandler MyEvent; }
i also added a CustomEventArgs class to my shared assembly (System.EventArgs wasn't sufficient for my application, but you could just use EventArgs if you don't need to supply some custom information to your Eventhandler) then (maybe the most important thing) add an eventwrapper to your shared assembly:[Serializable] public class MyEventWrapper: MarshalByRefObject { public event EventHandler OnWrapperMessage; public void WrapperMessagehandler(object sender,CustomEventArgs e) { if(OnWrapperMessage!=null) { OnWrapperMessage(sender, e); } } public override object InitializeLifetimeService() { return null; //that your object doesn't expire } }
now you can use the event in your client the following way:IMyServiceInterface service = //.. use Activator to retrieve your remoting service; MyEventWrapper w = new MyEventWrapper(); service.OnLogData += w.WrapperMessagehandler; w.OnWrapperMessage += handler_formyevent; ... void handler_formyevent(object sender, CustomEventArgs e) { // .. do something }
maybe it looks a little bit complicating but that was how i managed the problem that you cannot use events in a normal way over remoting channels. i hope this helpsThanks. That seems to be pretty much what I ended up doing. The article I was going off of called it an event shim. One thing that isn't really clear to me is why the wrapper/shim works. In other words, you can't just do
service.OnLogData += handler_formyevent;
You have to give it to the wrapper, which can subscribe (why, I'm not entirely sure), and then subscribe to the events that it raises.MyEventWrapper w = new MyEventWrapper(); service.OnLogData += w.WrapperMessagehandler; w.OnWrapperMessage += handler_formyevent;
hmmm...is it because the wrapper is known to both assemblies that it works, whereas doing it the other way, the service isn't really aware of the subscriber? So in the scenario where it doesn't really know about the subscriber it can't grab a remote reference to it, so that it can marshal the events over? I hope that makes sense...is it correct? BW