我們在使用MQ搭建系統的時候,經常要開放隊列給外接系統訪問。外接系統的穩定性是不可控的。為了防止外接系統不穩定導致誤操作破壞了MQ的配置或數據,需要對MQ做比較精細的權限控制。
我的需求是這樣的:
我有一個數據查詢服務,並且通過MQ推送數據變動消息。對接MQ的每個系統都會有自己一個獨立的隊列來讀取消息。所有消息通過一個扇形交換機廣播到所有隊列。我需要這個交換機和所有隊列都由管理員統一創建好。而其他系統使用的用戶,均沒有創建交換機和隊列的權限。數據查詢服務只擁有推送消息的權限,其他對接MQ的系統只擁有從自己隊列讀取消息的權限。
我們使用的MQ是RabbitMQ。我在網上搜了一下,大部分講的是用戶角色配置。對於MQ的資源授權管理講的比較少。以下內容將主要講解RabbitMQ權限控制的基本概念和模型。理解了這些基本概念后,應該可以愉快地使用RabbitMQ管理界面進行授權操作。如果你們只有命令行可用,也能很輕松地找到相應的命令。
RabbitMQ初始化
RabbitMQ初次啟動時,初始創建這兩個東西:
- 一個名稱為
/
的virtual host - guest用戶,擁有
/
的全部權限,只能localhost訪問
RabbitMQ授權模型
第一級控權單位是virtual host,virtual host下面第二級的控權單位是resource(包含exchange和queue)。兩個相同名稱的resource如果分屬不同的virtual host,則算是不同的resource。
什么是virtual host:
RabbitMQ is multi-tenant system: connections, exchanges, queues, bindings, user permissions, policies and some other things belong to virtual hosts, logical groups of entities.
就是說RabbitMQ是多租戶系統,簡單理解就是把多virtual host當做多個MQ系統來用就好了……
當用戶訪問MQ時,首先觸發第一級控權,判斷用戶是否有訪問該virtual host的權限。
若可訪問,則進行第二級控權,判斷用戶是否具有操作(operation)所請求的資源的權限。
RabbitMQ定義了操作(operation)有這么三種:
- configure:主要對應創建exchange和queue操作;
- write:write主要對應綁定和推送消息操作;
- read:read主要對應讀取消息操作。
后面有個表格列出了具體的對應關系。
當管理員對一個用戶進行授權時,要配置兩個元素:
- 允許什么操作,即configure、write、read三種operation;
- 操作什么resource。用戶是否擁有某資源的權限,通過對該資源的名稱與授權時配置的正則進行匹配來判斷。
下面這張表詳細描述了operation、resource和用戶可執行的操作的關系:
例子:
- 如果要給用戶授權可以往exchange
foo
推消息,則我們找到basic.publish這行,格子不是空的只有write這列,所以我們需要給用戶授權一個write權限,其正則可以匹配字符串foo
(比如說^foo$
,或者.*
等)。 - 如果要給用戶授權只能從queue
bar
讀取消息,則需要給用戶授權一個read權限,其正則可以匹配字符串bar
。
進一步了解
本文內容基本來自官網手冊,如果需要更詳細的說明——比如說topic的授權,可以直接看手冊。很多時候,當你剛接觸一個新工具時,比起在互聯網上瞎逛,直接閱讀官方手冊效率會高很多。雖然手冊比較冗長,而且大部分只有純英文,但畢竟最遠的路,就是最快的捷徑。