I am developing a log collector where different applications send tracing messages to a predefined RabbitMQ queue.
Every producer authorizes itself connecting to rabbitmq server. Is there a way to distinguish producers at the consumer level using the authorisation information provided during sending the message?
I would like to add the producer's username to the message header. So the consumer could read it out. Is there a way to achieve this within RabbitMQ?
Update: all the folks who leave a negative vote on the question. Could you give me a hint, what is wrong with it?
RabbitMQ supports a special message property "user-id".
In Java one can set it like this:
Channel channel = connection.createChannel();
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
.userId("user42")
.contentType("text/plain")
.build();
String message = "Hello World!";
channel.basicPublish("", QUEUE_NAME, props, message.getBytes());
If the property is set, RabbitMQ validates the user and throws an exception, if the provided user-id
doesn't match (case-sensitive) the username used for sending the message.
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - user_id property set to 'user42' but authenticated user was 'admin', class-id=60, method-id=40)
The receiver can read the information and authorize the producer this way.
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String messageIn = new String(delivery.getBody());
String userId = delivery.getProperties().getUserId();
System.out.println(" [x] Received '" + messageIn + "' from " + userId);
};
channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });
If using OAuth authentication, the username seams to be a claim which is used as a scope. For example, you can configures oid
as a scope claim for an Azure Entra ID Token in your rabbitmq.conf
file:
auth_oauth2.additional_scopes_key = oid
In this case the username expected in the user-id
property will be the Object ID of your service principal. It is a UUID like 30087a5b-0cc3-44ac-9e3f-868dbb0b5b8e
.