Custom two-pass serializer in 2.7.4

120 views
Skip to first unread message

Jean Lambert

unread,
Jun 7, 2013, 6:08:24 PM6/7/13
to masstrans...@googlegroups.com
Hi,
 
Just wondering if I'm missing something obvious or not here.
 
I'm developing a serializer which acts much like the PreSharedKeyEncryptedMessageSerializer. In essence, it uses a wrapped serialized (JsonMessageSerializer) to do the actual serialization, then performs an encryption transformation and uses the wrapped serializer to serialize the encrypted message.
 
Using MassTransit 2.7.4, there seems to be something new in Endpoint.Receive in which the following line performs a lookup on available serializers:
 

if (!_supportedSerializers.TryGetSerializer(acceptContext.ContentType, out serializer))

The problem I am having is the receiving bus never picks my serializer since it bases its choice on content type.
 
The class SupportedMessageSerializers uses the content type to match a serializer, which in this case is rightfully "application/vnd.masstransit+json"
 
However, my custom serializer does sets the content type correctly but never gets called to deserialize because of the above.
 
At ServiceBus configuration, I do correctly set the default serializer to my custom serializer, but this lookup section in the Endpoint.Receive method considers all serializers and never selects the right one.
 
Any idea what I am doing wrong?

Chris Patterson

unread,
Jun 7, 2013, 6:58:46 PM6/7/13
to masstrans...@googlegroups.com
You need to register it on the bus configuration so that it can use the content type for deserialization.

            configurator.SupportMessageSerializer<YourCustomMessageSerializer>();




--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/masstransit-discuss/62f1a43b-f498-4401-9b6c-186534dcda53%40googlegroups.com?hl=en-US.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Jean Lambert

unread,
Jun 7, 2013, 7:09:39 PM6/7/13
to masstrans...@googlegroups.com
Hi, that doesn't seem to do the trick since my serializer does not have a parameter-less constructor. Even adding one does not produce the desired behaviour.

Lets take for example the PreSharedKeyEncryptedMessageSerializer, it has its own ContentType of "application/vnd.masstransit+psk" but just after its done encrypting in Serialize(), it does the second serialization pass using its wrapped serializer. Say this was an instance of the JsonMessageSerializer, the message ContentType would then be "application/vnd.masstransit+json". On the receiving side, this would be interpreted as a JSON message which would select the JsonMessageSerializer instead of the PreSharedKeyEncryptedMessageSerializer based on the ContentType.

Maybe there is something I'm getting wrong here, but even by registering the ContentType of my custom serializer, since it is two pass, it will always present itself as a ContentType of the wrapped serializer.


On Friday, June 7, 2013 6:58:46 PM UTC-4, Chris Patterson wrote:
You need to register it on the bus configuration so that it can use the content type for deserialization.

            configurator.SupportMessageSerializer<YourCustomMessageSerializer>();


On Fri, Jun 7, 2013 at 3:08 PM, Jean Lambert <jeanlamb...@gmail.com> wrote:
Hi,
 
Just wondering if I'm missing something obvious or not here.
 
I'm developing a serializer which acts much like the PreSharedKeyEncryptedMessageSerializer. In essence, it uses a wrapped serialized (JsonMessageSerializer) to do the actual serialization, then performs an encryption transformation and uses the wrapped serializer to serialize the encrypted message.
 
Using MassTransit 2.7.4, there seems to be something new in Endpoint.Receive in which the following line performs a lookup on available serializers:
 

if (!_supportedSerializers.TryGetSerializer(acceptContext.ContentType, out serializer))

The problem I am having is the receiving bus never picks my serializer since it bases its choice on content type.
 
The class SupportedMessageSerializers uses the content type to match a serializer, which in this case is rightfully "application/vnd.masstransit+json"
 
However, my custom serializer does sets the content type correctly but never gets called to deserialize because of the above.
 
At ServiceBus configuration, I do correctly set the default serializer to my custom serializer, but this lookup section in the Endpoint.Receive method considers all serializers and never selects the right one.
 
Any idea what I am doing wrong?

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.

Chris Patterson

unread,
Jun 7, 2013, 7:24:47 PM6/7/13
to masstrans...@googlegroups.com
Your serializer should be the one that is setting the content type of the message, so it should be written to the transport as yours.

As for overlooking the configuration option to specify the actual serializer instance, I'll see if that can be added. 


To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.

Jean Lambert

unread,
Jun 7, 2013, 7:38:16 PM6/7/13
to masstrans...@googlegroups.com
Yes, I do set the content type in my customer serializer, just as is done in the PreSharedKeyEncryptedMessage Serializer below:

EncryptedStream encryptedStream = cryptographyService.Encrypt(readStream);


var encryptedMessage = new EncryptedMessageEnvelope

{

CipheredMessage = Convert.ToBase64String(encryptedStream.GetBytes()),

Iv = Convert.ToBase64String(encryptedStream.Iv),

};


var encryptedContext = new SendContext<EncryptedMessageEnvelope>(encryptedMessage);

encryptedContext.SetUsing(context);

encryptedContext.SetMessageType(typeof (EncryptedMessageEnvelope));

encryptedContext.SetContentType(ContentTypeHeaderValue);


_wrappedSerializer.Serialize(output, encryptedContext);


That last bit (_wrappedSerializer.Serialize(output, encryptedContext)) overrides this ContentType. For example, in 2.7.4, the following example doesn't function:

var bus = ServiceBusFactory.New(sbc =>

    {

        sbc.SetPurgeOnStartup(true);

        sbc.ReceiveFrom("loopback://127.0.0.1/self");

        //sbc.SupportMessageSerializer<PreSharedKeyEncryptedMessageSerializer>(); // Causes a compilation error

        sbc.SetDefaultSerializer(new PreSharedKeyEncryptedMessageSerializer("eguhidbehumjdemy1234567890123456", new JsonMessageSerializer()));

        sbc.Subscribe(s => s.Handler<Message>(m => Console.WriteLine(m.Content)));

    });


bus.Publish(new Message { Content = "hello" });

Console.WriteLine("Press key to continue");

Console.ReadKey();


bus.Dispose();


The message is never received.

On Friday, June 7, 2013 7:24:47 PM UTC-4, Chris Patterson wrote:
Your serializer should be the one that is setting the content type of the message, so it should be written to the transport as yours.

As for overlooking the configuration option to specify the actual serializer instance, I'll see if that can be added. 
On Fri, Jun 7, 2013 at 4:09 PM, Jean Lambert <jeanlamb...@gmail.com> wrote:
Hi, that doesn't seem to do the trick since my serializer does not have a parameter-less constructor. Even adding one does not produce the desired behaviour.

Lets take for example the PreSharedKeyEncryptedMessageSerializer, it has its own ContentType of "application/vnd.masstransit+psk" but just after its done encrypting in Serialize(), it does the second serialization pass using its wrapped serializer. Say this was an instance of the JsonMessageSerializer, the message ContentType would then be "application/vnd.masstransit+json". On the receiving side, this would be interpreted as a JSON message which would select the JsonMessageSerializer instead of the PreSharedKeyEncryptedMessageSerializer based on the ContentType.

Maybe there is something I'm getting wrong here, but even by registering the ContentType of my custom serializer, since it is two pass, it will always present itself as a ContentType of the wrapped serializer.


On Friday, June 7, 2013 6:58:46 PM UTC-4, Chris Patterson wrote:
You need to register it on the bus configuration so that it can use the content type for deserialization.

            configurator.SupportMessageSerializer<YourCustomMessageSerializer>();


On Fri, Jun 7, 2013 at 3:08 PM, Jean Lambert <jeanlamb...@gmail.com> wrote:
Hi,
 
Just wondering if I'm missing something obvious or not here.
 
I'm developing a serializer which acts much like the PreSharedKeyEncryptedMessageSerializer. In essence, it uses a wrapped serialized (JsonMessageSerializer) to do the actual serialization, then performs an encryption transformation and uses the wrapped serializer to serialize the encrypted message.
 
Using MassTransit 2.7.4, there seems to be something new in Endpoint.Receive in which the following line performs a lookup on available serializers:
 

if (!_supportedSerializers.TryGetSerializer(acceptContext.ContentType, out serializer))

The problem I am having is the receiving bus never picks my serializer since it bases its choice on content type.
 
The class SupportedMessageSerializers uses the content type to match a serializer, which in this case is rightfully "application/vnd.masstransit+json"
 
However, my custom serializer does sets the content type correctly but never gets called to deserialize because of the above.
 
At ServiceBus configuration, I do correctly set the default serializer to my custom serializer, but this lookup section in the Endpoint.Receive method considers all serializers and never selects the right one.
 
Any idea what I am doing wrong?

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsubscribe...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.

Chris Patterson

unread,
Jun 8, 2013, 1:00:20 PM6/8/13
to masstrans...@googlegroups.com
You need to serializer with the wrapper serializer first, then your serializer and set the content type.


To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.

Jean Lambert

unread,
Jun 10, 2013, 8:55:42 AM6/10/13
to masstrans...@googlegroups.com
Hi Chris,
 
Thanks for the info.
 
I couldn't agree with you more and based on that, I think there is a bug in the following serializer provided with MassTransit in which the wrapped serializer is called at the end, therefore setting the content type and overriding "application/vnd.masstransit+psk"
 

MassTransit.Serialization.PreSharedKeyEncryptedMessageSerializer

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.
To post to this group, send email to masstrans...@googlegroups.com.

Jean Lambert

unread,
Jun 10, 2013, 10:53:31 AM6/10/13
to masstrans...@googlegroups.com
Hi Again,
 
After much time spent experimenting, is it possible that the Serialize method of the PreSharedKeyEncryptedMessageSerializer is missing the following line just after that last _wrappedSertializer.Serialize(...) call?
 

context.SetContentType(ContentTypeHeaderValue);

 
My reasoning is as follows, at the transport level (in my case using RabbitMq, see: OutboundRabbitMqTranport.cs:Send()) the content type is taken from the 'context' instance which is passed to the Serialize method.
 
Currently, the actual content type "application/vnd.masstransit+psk" is only set on the locally created encryptedContext instance which is used in that last serialization pass but the actual content type never makes it out of that method since it was not correctly set to the context parameter passed in the first place. So, basically, this means that the following line, only serve for serialization but fail to pass the correct content type to the transport:
 

var encryptedContext = new SendContext<EncryptedMessageEnvelope>(encryptedMessage);

encryptedContext.SetUsing(context);

encryptedContext.SetMessageType(typeof (EncryptedMessageEnvelope));

encryptedContext.SetContentType(ContentTypeHeaderValue);

_wrappedSerializer.Serialize(output, encryptedContext);

Bob de Ruin

unread,
Jul 24, 2013, 8:59:08 AM7/24/13
to masstrans...@googlegroups.com
Hello Cris,Jean
 
I have been using the PreSharedKeyEncryptedMessageSerializer as is, using MassTransit 2.7.0. without any problems. After upgrading to version 2.7.4. it stops working. Removing the SetDefaultSerializer(mySerializer) line from the configuration solves the problem, but of course leaves me with unencrypted messages. Reading this thread makes me think it might be releated.
 
@Cris: is this considered a bug? Will it be fixed in the next version? Should I try and assist?
@Jean: Did you test your suggested change? And is it working for you now?
 
Regards,
Bob.
 

Travis Smith

unread,
Jul 24, 2013, 9:09:44 AM7/24/13
to masstrans...@googlegroups.com
Bob, I'd drop an issue in https://github.com/MassTransit/MassTransit/issues. If you have a failing unit test, all the better.

-Travis


 

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.

Jean Lambert

unread,
Jul 24, 2013, 9:27:12 AM7/24/13
to masstrans...@googlegroups.com
Hi guys,
 
I already fixed this in https://github.com/phatboyg/MassTransit/pull/90 which also includes related unit tests.
 
The problem was twofold:
 
  • MassTransit 2.7.4 introduces support for multiple serializers but there is no way to override this behavior to achieve 100% secure communication using the PreSharedKeyEncryptedMessageSerializer. Hence, no matter what you request as your default serializer, any inbound message can be deserialized by any of the serializers found in MassTransit. You can now implement your own ISupportedMessageSerializers which contain ONLY your secure to be used for inbound.

 

  • The other issue is with the PreSharedKeyEncryptedMessageSerializer does not currently set its content type to "application/vnd.masstransit+psk". It in fact sets it to the content type of the wrapped serializer. So, if you are using the JSON serializer, any encrypted message will be marked as being of type "application/vnd.masstransit+json" which is wrong and will cause the Endpoint.Receive's call to _supportedSerializers.TryGetSerializer(acceptContext.ContentType,

    out serializer) to pick the JSONMessageSerializer instead of the PreSharedKeyEncryptedMessageSerializer. Now, by setting the contentType correctly after the serialization by the wrapped serializer fixes this.

Chris should pull this into his dev branch and eventually release it. In the mean time, you either have to stay with 2.7.2 or run you own built version of MassTransit with the fix.
 
On Wednesday, July 24, 2013 9:09:44 AM UTC-4, Travis Smith wrote:
Bob, I'd drop an issue in https://github.com/MassTransit/MassTransit/issues. If you have a failing unit test, all the better.

-Travis


On Wed, Jul 24, 2013 at 8:59 AM, Bob de Ruin <schri...@gmail.com> wrote:
Hello Cris,Jean
 
I have been using the PreSharedKeyEncryptedMessageSerializer as is, using MassTransit 2.7.0. without any problems. After upgrading to version 2.7.4. it stops working. Removing the SetDefaultSerializer(mySerializer) line from the configuration solves the problem, but of course leaves me with unencrypted messages. Reading this thread makes me think it might be releated.
 
@Cris: is this considered a bug? Will it be fixed in the next version? Should I try and assist?
@Jean: Did you test your suggested change? And is it working for you now?
 
Regards,
Bob.
 

--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-discuss+unsub...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.

Bob de Ruin

unread,
Jul 24, 2013, 9:56:08 AM7/24/13
to masstrans...@googlegroups.com
Hi Jean/Travis,
 
I followed up on Travis's suggestion and created a new issue on https://github.com/MassTransit/MassTransit/issues. Should I remove it because it is already acknoleged  and will be fixed in the next version?
 
Regards,
Bob.

Jean Lambert

unread,
Jul 24, 2013, 9:58:13 AM7/24/13
to masstrans...@googlegroups.com
Mark it as duplicate and close it.

Chris Patterson

unread,
Jul 24, 2013, 11:13:46 AM7/24/13
to masstrans...@googlegroups.com
I'm going to try and release updates in the next week or so to NuGet, I have a few other fixes to get into the codebase first though.



--
You received this message because you are subscribed to the Google Groups "masstransit-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to masstransit-dis...@googlegroups.com.

To post to this group, send email to masstrans...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages