Remoting, Events and the 1.1 Framework
This weekend I played with the Observer Pattern to create a system that could publish events to a central server. To this server, other applications could subscribe to receive this events. Because I wanted the system to be fast, I choose .NET Remoting as communication between the clients and the server.
I implemented the pattern, and when I wanted to test my
creation, I immediately got the following exception:
An unhandled exception of type
'System.Runtime.Serialization.SerializationException'
occurred in mscorlib.dll
Additional information: Because of security restrictions, the type System.Runtime.Remoting.ObjRef cannot be accessed.
After some searching, I discovered that the problem was a
security setting change in the 1.1 version of the .NET
Framework. Luckely it was quite well documented on the
GotDotNet site. <quote>Any remoting system that relies on run-time type
validation must deserialize a remote stream to begin using
it, and malicious clients could use the moment of
serialization or deserialization to the detriment of your
application. To protect against such clients, .NET
remoting provides two levels of automatic deserialization,
Low and Full. Low is the default value, and enables most
basic remoting functionality, such as automatic
deserialization of remoting infrastructure types, and a
limited set of system-implemented types. Full supports
automatic deserialization of all types that remoting
supports in all situations. See below for a complete
description of the settings.
Do not assume that
controlling deserialization is the only security your
application needs. In distributed applications even a high
degree of control over serialization will not prevent
malicious clients from intercepting the communication and
using that in some way. Therefore, although the Low
deserialization level will protect the remoting server
from being directly exploited, you must still use
authentication and encryption to completely protect your
investment in your data.</quote>
So since 1.1 the automatically deserialization of custom
types is turned off by default. The workaround is to open a
channel that allows the full serialization level. You can do
it like this:
Dim channel As Channels.Tcp.TcpChannel
Dim provider
As New
System.Runtime.Remoting.Channels.BinaryServerFormatterSinkProvider
provider.TypeFilterLevel
=
System.Runtime.Serialization.Formatters.TypeFilterLevel.Full
Dim
props As New Hashtable
props.Add("port", 2333)
channel
= New Channels.Tcp.TcpChannel(props, Nothing, provider)
Channels.ChannelServices.RegisterChannel(channel)