您的位置:首页 > 其它

【转】RabbitMQ入门_15_访问控制

2018-10-05 09:01 113 查看

转自首夜盲毒预言家

参考资料:https://www.rabbitmq.com/access-control.html

A. 核心概念

  • Virtual Host:虚拟主机为 RabbitMQ 中的资源提供了逻辑分组与隔离
  • 资源:资源是虚拟主机中的实体,例如队列和交换机。不同虚拟主机中的同名实体是不同的资源

 

B. Rabbit 访问控制基本流程

当客户端尝试建立到 RabbitMQ 的连接时,必须指定虚拟主机和用户密码。如果用户密码正确,同时该用户在该虚拟主机配置过任何权限,则可以建立连接,否则拒绝连接。

连接建立后,任何对该虚拟主机中资源的操作都会触发权限检查。
 

C. 权限

RabbitMQ 中每一个资源都对应了三种权限类型:

  • configure: 创建与销毁资源
  • write:向资源注入消息
  • read:从资源获取消息



用户是否拥有某个资源的某种权限类型可以看成是一个最小粒度的权限(这不是官方文档原意,只是个人理解)。

任何对资源的操作,RabbitMQ 都会检查该用户是否有合适的权限。下表列出所有对资源的操作分别需要什么样的权限:
 

AMQP 0-9-1 Operation   configure write read
exchange.declare (passive=false) exchange    
exchange.declare (passive=true)      
exchange.declare (with AE) exchange exchange (AE) exchange
exchange.delete   exchange    
queue.declare (passive=false) queue    
queue.declare (passive=true)      
queue.declare (with DLX) queue exchange (DLX) queue
queue.delete   queue    
exchange.bind     exchange (destination) exchange (source)
exchange.unbind     exchange (destination) exchange (source)
queue.bind     queue exchange
queue.unbind     queue exchange
basic.publish     exchange  
basic.get       queue
basic.consume       queue
queue.purge       queue

 

例如第5行的 queue.declare (passive=false) 操作,即之前我们调用的 

senderChannel.queueDeclare("test", true, false, false, null);
,它要求用户对 test 队列(资源)有 configure 操作权限。如果没有该权限,申明队列的请求会抛出异常,哪怕该队列实际已经存在都不行。

而根据第6行,哪怕用户对 test 队列没有任何权限,也可以通过 

senderChannel.queueDeclarePassive("test");
 申明该队列。(当然,就算不申明,该队列也是可以直接使用的。passive 方式的申明只是用来判断队列是否已经存在)

 

D. 设置权限

https://www.rabbitmq.com/man/rabbitmqctl.1.man.html#Access%20control

通过 rabbitmqctl 的 set_permissions 命令可以为用户设置权限,命令格式为:

set_permissions [-p vhost] {user} {conf} {write} {read}

  • vhost:虚拟主机的名字,默认的虚拟主机是 "/"。
  • user:用户名
  • conf:一个正则表达式,用户对符合该正则表达式的所有资源拥有 configure 操作的权限
  • write:一个正则表达式,用户对符合该正则表达式的所有资源拥有 write 操作的权限
  • read:一个正则表达式,用户对符合该正则表达式的所有资源拥有 read 操作的权限



实例:

rabbitmqctl set_permissions -p /myvhost test "^test-.*" ".*" ".*"
 为 test 用户在 /myvhost 虚拟主机中设置以下权限:对 test- 开头的资源赋予 configure 权限,对所有资源赋予 write 和 read 权限。

显然,一个用户对一个虚拟主机只能设置一条权限配置,这对正则表达式的定义提出了要求,也对资源命名规则提出了要求。
 

E. 实战

本文涉及的所有功能都可以通过管理插件在管理页面操作。

我们将创建 test 用户,使其可以访问 /test 虚拟主机,同时对 /test 虚拟主机中名字为 hello 的资源具有 configure 权限,所有资源具有 write 和 read 权限:

  • 在管理页面 Admin > Users 页创建用户 test
  • 在管理页面 Admin > Virtual Hosts 页创建虚拟主机 /test
  • 在虚拟主机列表中点击 /test 虚拟主机,进入详细信息页面
  • 在 Permissions 区段中选择 test 用户,将 Configure regexp 设置为 hello,其它不变,点击 Set permission 按钮



gordon.study.rabbitmq.accesscontrol.TestAccessControl.java

[code]<span style="color:#333333"><code><span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#a31515">TestAccessControl</span> {

<span style="color:#0000ff">private</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">final</span> String QUEUE_NAME = <span style="color:#a31515">"test"</span>;

<span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">void</span> <span style="color:#a31515">main</span>(String[] argv) <span style="color:#0000ff">throws</span> Exception {
ConnectionFactory factory = <span style="color:#0000ff">new</span> ConnectionFactory();
factory.setHost(<span style="color:#a31515">"localhost"</span>);
factory.setVirtualHost(<span style="color:#a31515">"/test"</span>);
factory.setUsername(<span style="color:#a31515">"test"</span>);
factory.setPassword(<span style="color:#a31515">"test123"</span>);
Connection connection = factory.newConnection();
Channel senderChannel = connection.createChannel();
<span style="color:green">// senderChannel.queueDeclare(QUEUE_NAME, true, false, false, null); // throw Exception</span>
senderChannel.queueDeclarePassive(QUEUE_NAME);
senderChannel.basicPublish(<span style="color:#a31515">""</span>, QUEUE_NAME, <span style="color:#0000ff">null</span>, <span style="color:#a31515">"test"</span>.getBytes(<span style="color:#a31515">"UTF-8"</span>));
}
}</code></span>
阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: