參考 http://blog.163.com/sky20081816@126/blog/static/16476102320107173226920/
http://blog.csdn.net/kevin3101/article/details/53609180
question 1: what is virtual_host
2:How does it work
一. what is it
There are four building blocks you really care about in AMQP: virtual hosts, exchanges, queues and bindings. A virtual host holds a bundle of exchanges, queues and bindings. Why would you want multiple virtual hosts? Easy. A username in RabbitMQ grants you access to a virtual host…in its entirety. So the only way to keep group A from accessing group B’s exchanges/queues/bindings/etc. is to create a virtual host for A and one for B. Every RabbitMQ server has a default virtual host named 「/」. If that’s all you need, you’re ready to roll.
in its entirety:做爲一個總體
紅色部分語句的意思:vhost是rabbitmq分配權限的最小細粒度。好比咱們能夠爲一個用戶分配一個能夠訪問哪一個或者哪一些vhost的權限。可是不能爲用戶分配一個能夠訪問哪一些exchange,或者queue的權限,由於rabbitmq的權限細粒度沒有細化到交換器和隊列,他的最小細粒度是vhost(vhost中包含許多的exchanges,queues,bingdings)。因此若是exchangeA 和queueA 只能讓用戶A訪問,exchangeB 和queueB 只能讓用戶B訪問,要達到這種需求,只能爲exchangeA 和queueA建立一個vhostA,爲exchangeB 和queueB 建立vhostB,這樣就隔離開來了。
補充:一個broker能夠開設多個vhost,用於不一樣用戶的權限分離
virtualHost is used as a namespace for AMQP resources (default is \"/\"), so different applications could use multiple virtual hosts on the
same AMQP server
virtual host只是起到一個命名空間的做用,因此能夠多個user共同使用一個virtual host,文章開頭寫的vritual_host = '/',這個是系統默認的,就是說當咱們建立一個到rabbitmq的connection時候,它的命名空間是'/',須要注意的是不一樣的命名空間之間的資源是不能訪問的,好比 exchang,queue ,bingding等
二.How does it work
既然vitrual host 只是一個命名空間,那麼咱們就能夠本身建立一個嘍,怎麼去幹呢?這裏咱們須要用到工具 :rabbitmqctl,安裝rabbitMQ的時候已經安裝好了。這真是一個強大的工具阿。輸入 ./rabbitmqctl,咱們能夠看到
首先咱們能夠創建一個測試用戶(若是你想用系統默認的guest也能夠)
rabbitmqctl add_user test 123456 ,這樣咱們就新建了一個能夠連到rabbitmq的用戶,用戶名時test,密碼是123456
咱們能夠用 rabbitmqctl list_users 看看有多少個用戶了,能夠看到有guest和test了吧
而後 咱們經過 rabbitmqctl add_vhosts命令新建一個virtual host : rabbitmqctl add_vhosts test_host
咱們經過 rabbitmqctl list_vhosts命令看看如今系統有幾個vhost了。能夠看到有兩個,一個是系統默認的 '/', 還有一個就 是咱們新建的 test_host。
可是到這裏是不夠的,咱們只是聲明瞭一個vhost,咱們還要給它分配訪問權限。
rabbitmqctl set_permissions -p test_host test "test-*" ".*" ".*",如此用戶名爲test的用戶就能夠訪問vitrual host爲test_host的資源了,而且具有讀寫的權限。
rabbitmqctl set_permissions -p /vhost1 user_admin ".*" ".*" ".*" ,命令使用戶user_admin具備/vhost1這個virtual host中全部資源的配置、寫、讀權限以便管理其中的資源
對何種資源具備配置、寫、讀的權限經過正則表達式來匹配,具體命令以下:
set_permissions [-p <vhostpath>] <user> <conf> <write> <read>
其中,<conf> <write> <read>的位置分別用正則表達式來匹配特定的資源,如'^(amq\.gen.*|amq\.default)$'能夠匹配server生成的和默認的exchange,'^$'不匹配任何資源
須要注意的是RabbitMQ會緩存每一個connection或channel的權限驗證結果、所以權限發生變化後須要重連才能生效。
Vhost的權限
關於rabbitmq權限的幾點:
rabbitmq的權限控制經過兩層來實現,一是vhost的權限,二是確認有權限訪問vhost後,對vhost內資源的權限控制(配置,讀,寫)
1.默認的guest用戶
安裝rabbitmq(3.3.1),並啓用management plugin後,使用默認的帳號guest登錄管理控制檯,卻提示登錄失敗。正則表達式
翻看官方的release文檔後,得知因爲帳號guest具備全部的操做權限,而且又是默認帳號,出於安全因素的考慮,guest用戶只能經過localhost登錄使用,並建議修改guest用戶的密碼以及新建其餘帳號管理使用rabbitmq(該功能是在3.3.0版本引入的)。緩存
雖然能夠以比較猥瑣的方式:將ebin目錄下rabbit.app中loopback_users裏的<<"guest">>刪除,或者在配置文件rabbitmq.config中對該項進行配置,安全
2.權限工做流程
一個客戶端鏈接到服務器後,指定一個所操做虛擬機。這是權限產生做用的第一層,服務器會檢查該用戶是否有權限訪問該虛擬機,有則進行下一層,不然拒絕鏈接。
資源,如一個虛擬機內的交換器、隊列等,在資源上rabbitmq提供三種類型的操做,配置、讀、寫。當客戶端被容許鏈接到某虛擬機後,服務器根據客戶端所擁有的權限,容許其作相應的操做。
權限配置支持正則表達式,能夠實現必定粒度的權限控制,好比說對某一類隊列的控制。
3.rabbitmqctl中對用戶的管理命令
rabbitmqctl list_users
add_user {username} {password}
#rabbitmqctl add_user admin 123456
delete_user {username}
#rabbitmqctl delete_user admin
change_password {username} {newpassword}
#rabbitmqctl change_password admin 111111
clear_password {username}
#rabbitmqctl clear admin
set_user_tags {username} {tag ...}
#rabbitmqctl set_user_tags admin administrator #可跟多少tag,tag爲空的時候表示清除原有
set_permissions [-p vhost] {user} {conf} {write} {read}
#rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
clear_permissions [-p vhost] {username}
list_permissions [-p vhost]
#rabbitmqctl list_permissions -p "/"
list_user_permissions {username}
#rabbitmqctl list_user_permissions admin
咱們在獲取設備鏈接的時候能夠指定用戶,而且指定vhost,固然該用戶須要有該vhost的權限才能夠。
ConnectionFactory factory =
new ConnectionFactory();
factory.setUsername(
userName);//指定用戶
factory.setPassword(
password);//用戶密碼
factory.setVirtualHost(
virtualHost); //指定vhost
factory.setHost(
hostName);//指定rabbitmq服務器的主機
factory.setPort(
portNumber);//指定rabbitmq服務器所監聽的端口號
Connection conn = factory.newConnection();
目前還有的疑問:
1.一次鏈接,只能指定一個vhost嗎?
2.用戶和vhost的關係,是多對多嗎?
3.若是是,那麼在建立鏈接以後,咱們的消費者可否指定的從某一個vhost的某一個queue去接收數據,或者生產者可否指定的向某一個vhost的exchange發送數據。
意思就是若是一個用戶能夠擁有多個vhost的權限,是否能夠建立一次鏈接,而後動態的切換vhost。
關於rabbitmq權限的文章
http://blog.csdn.net/zyz511919766/article/details/42292655