文章目錄
RabbitMQ 關於寫入部份 Queue 的權限設定
之前筆記 RabbitMQ 為不同帳號設定不同 Queue 權限 紀錄到讓不同 user 有不同權限,當時的情境是以讀取資料為例,最近同事想要為寫入也加上不同權限設定,依照之前的做法卻無法成功生效,我重新確認後發現之前筆記觀念不是完全正確,趁這個機會梳理一下規則,希望下次不要再打自己臉了XD
基本環境說明
- macOS Monterey 12.2.1
- docker desktop 4.2.0(70708)
docker images
- rabbitmq:3.9.13-management
.NET SDK 6.0.200
NuGet packages
- RabbitMQ.Client 6.2.1
簡化情境說明
- 一個 exchange 在 vhost root 下:yowkoex
- 兩個 queue binding 在 yowkoex 中:q1 (routing_key:1);q2 (routing_key:2)
- user:yowko 只有寫 q1 與讀 q2 的權限
rabbitmq 環境建立
使用 docker 啟動 rabbitmq
docker run -d --rm --name rabbitmq -p 5672:5672 -p 15672:15672 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=pass.123 rabbitmq:3.9.13-management
建立 user: yowko
rabbitmqctl add_user yowko pass.123
建立 exchange: yowkoex
rabbitmqadmin declare exchange name=yowkoex type=topic -u admin -p pass.123
建立 queue
q1
rabbitmqadmin declare queue name=q1 durable=true -u admin -p pass.123
q2
rabbitmqadmin declare queue name=q2 durable=true -u admin -p pass.123
將 exchange 與 queue 做 binding
q1
rabbitmqadmin declare binding source="yowkoex" destination_type="queue" destination="q1" routing_key="1" -u admin -p pass.123
q2
rabbitmqadmin declare binding source="yowkoex" destination_type="queue" destination="q2" routing_key="2" -u admin -p pass.123
存取訊息程式碼
static void Main(string[] args) { PublishMessage(); //ConsumeMessage(); } private static void PublishMessage() { var factory = new ConnectionFactory() { Uri = new Uri("amqp://yowko:pass.123@localhost:5672/") }; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { var message = $@"Hello World! @{DateTime.Now}"; var body = Encoding.UTF8.GetBytes(message); var props = channel.CreateBasicProperties(); channel.BasicPublish(exchange: "yowkoex", routingKey: "1", basicProperties: props, body: body); Console.WriteLine($"[x] Sent {message}"); } Console.WriteLine("Press [enter] to exit."); Console.ReadLine(); } private static void ConsumeMessage() { var factory = new ConnectionFactory() { Uri = new Uri("amqp://yowko:pass.123@localhost:5672/") }; using var connection = factory.CreateConnection(); using var channel = connection.CreateModel(); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body.ToArray(); var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] Received {0}", message); }; channel.BasicConsume(queue: "q2", autoAck: true, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine(); }
設定與說明
設定 user 權限
rabbitmqctl set_permissions -p / yowko "" "yowkoex" "q2"
針對存取的 resource 來做設定,寫入是對
exchange
,讀取是對queue
設定 user topic 權限
rabbitmqctl set_topic_permissions -p / yowko yowkoex "1" ""
針對指定 exchange 加上寫入的 routing key 限制,不過我不理解的為什麼讀取都是直接對 queue 怎麼會出現 rouiting key 限制設定
心得
- 嘗試發送訊息到沒有寫入權限的 q2 (routing_key 帶
2
) 不會拋出錯誤 嘗試從沒有讀取權限的 q1 接收訊息會出現錯誤
錯誤訊息
Unhandled exception. RabbitMQ.Client.Exceptions.OperationInterruptedException: The AMQP operation was interrupted: AMQP close-reason, initiated by Peer, code=403, text='ACCESS_REFUSED - access to queue 'q1' in vhost '/' refused for user 'yowko'', classId=60, methodId=20
錯誤截圖
參考資訊
文章作者 Yowko Tsai
上次更新 2022-03-12
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。