I want to use RabbitMQ to communicate between multiple applications which are deployed on different networks and are maintained by different people. As a receiver of a message (consumer) I want to be convinced that the sender of the message (producer) is who he claims to be. Best approach I can think for this would be message signing and verification of those signatures. As this is my first time doing something with RabbitMQ, I am kind of stuck on how to implement this.
Message senders and receivers are Java applications. I've decided to use Spring AMQP template to make things somewhat easier for me. In a perfect scenario I would like to somehow intercept the message when it's already a byte array/stream, sign this blob and attach the signature as a message header. On the receiving end I would again like to intercept the message before it's deserialized, verify the signature from header against the blob and if everything is OK then deserialize it. But I havent found any means in Spring-Rabbit for doing this.
There is a concept of MessagePostProcessor
in Spring-Rabbit, but when this is invoked, the message is still not fully serialized. It seems like something that I imagined would be solved somewhere by someone as it feels like a common problem to have, but my research has left me bare handed.
Currently I am using AmqpTemplate.convertAndSend
for message sending and @RabbitListener
for message receiving. But I am not stuck with Spring. I can use whatever I like. It just seemed like an easy way to get going. I am using Jackson for message serialization to/from JSON. Problem is how to intercept sending and receiving in the right place.
Backup plan is to put both data and signature in body and joint them with a wrapper but this would mean double serialization and is not as clean as I would like the solution to be.
So has anyone got experience with this stuff and can perhaps can advise me on how to approach this problem?
There is a concept of
MessagePostProcessor
in Spring-Rabbit, but when this is invoked, the message is still not fully serialized.
I am not sure what you mean by that; the MessagePostProcessor
is exactly what you need the body
is the byte[]
that will be sent to RabbitMQ. You can use an overloaded convertAndSend
method that takes an MPP, or add your MPP to the template (in the beforeSendMessagePostProcessors
).
On the receiving side, the listener container factory can be configured with afterReceiveMessagePostProcessors
. Again; the body
is the byte[]
received from RabbitMQ.