参考 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的权限验证结果、因此权限发生变化后需要重连才能生效。
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