RabbitMQ学习(二)---------请求许可

来源:互联网 发布:java构造器怎么理解 编辑:程序博客网 时间:2024/06/05 17:51

  如果你熟悉不同操作系统的访问控制列表的话,那么理解RabbitMQ的权限系统对你来说易如反掌。就像大多数权限系统那样,首先创建用户,然后为其赋予权限。如下图所示:

                             图 1     RabbitMQ权限工作原理:用户可以为连接到RabbitMQ主机的应用程序设置不同级别的权限(读,写和/或配置)


  RabbitMQ权限系统一个好的地方在于单个用户可以跨越多个vhost进行授权。当应用程序需要跨越多个安全域进行通信时(使用虚拟主机隔离),这会极大地方便访问控制的管理。让我们从创建用户开始吧。


管理用户

  在RabbitMQ中,用户是访问控制的基本单元。针对一到多个vhost,其可以被赋予不同级别的访问权限,并使用标准的用户名/密码对来认证用户。对用户的增加,删除以及列出列表,都非常简单。这些操作都是通过rabbitmqctl完成的。让我们为check-cashing应用程序创建一个新用户吧。

  从RabbitMQ安装目录下的./sbin运行如下命令:

root@ubuntu:/etc/rabbitmq#rabbitmqctl add_user cashing-tier cashMe1
Creating user "cashing-tier" ...


  这样就创建了一个新的Rabbit用户,用户名为cashing-tier,密码是cashMe1。如果想要删除用户,则只需简单运行如下命令:


root@ubuntu:/etc/rabbitmq# rabbitmqctl delete_user cashing-tier
Deleting user "cashing-tier" ...


  请注意,当你删除用户的时候,任何引用该用户的访问控制条目都会从Rabbit权限数据库中自动删除。同时,rabbitmqctl也不会警告你与用户相关的访问控制条目也会一并删除。所以请谨慎删除用户;否则你会发现不得不重建一大堆访问控制条目。

  你经常会需要知道在当前Rabbit服务器上存在哪些用户。通过传入list_user命令到rabbitmqctl就可以进行查看:

root@ubuntu:/etc/rabbitmq#rabbitmqctl list_users
Listing users ...
cashing-tier    []
guest   [administrator]
openstack       []


  你也许会问自己:”不错。不过,我如何更改已经存在的用户的密码呢?我需要重新创建用户?那不是会丢失用户的访问控制条目吗?”别害怕,rabbitmqctl早就考虑到了。只要简单运行change_password命令,指明需要更改密码的用户名称和新密码即可:

 root@ubuntu:/etc/rabbitmq#rabbitmqctl change_password cashing-tier compl3xPassword
Changing password for user "cashing-tier" ...



2.Rabbit的权限系统

从1.6.0版本开始,RabbitMQ实现了一套访问控制列表(ACL)风格的权限系统。在这以前,用户只能针对整个vhost进行授权或拒绝访问(对于已授权的vhost,用户可以做任何事情)。新的权限系统允许大量细粒度控制,同时可以授予用户读,写和配置权限。那么这三者之间有何差异?

  • 读--------有关消费消息的任何操作,包括“清除”整个队列(同样需要绑定操作的成功)
  • 写--------发布消息(同样需要绑定操作的成功)
  • 配置------队列和交换器的创建和删除

                    表1      AMQP操作到RabbitMQ权限的映射关系
AMQP命令配置写读exchange.declareexchange  exchange.deleteexchange  queue.declarequeue  queue.deletequeue  queue.bind queueexchangebasic.publish exchange basic.get  queuebasic.consume  queuequeue.purge  queue                               

每一条访问控制条目由以下四部分组成:

  • 被授予访问权限的用户。
  • 权限控制应用的vhost。
  • 需要授予的读/写/配置权限的组合。
  • 权限范围-----------权限控制仅应用于客户端命名的队列/交换器呢,还是仅用于服务器端命名的队列/交换器呢?抑或两者兼顾?客户端命名意味着由你的应用程序设置了交换器/队列的名称;服务器端命名意味着你的应用程序不提供名字而是让服务器随机指派。

谨记:访问控制条目是无法跨越vhost的。举例来说,如果你想要给用户cashing-tier在vhost oak和vhost sycamore上赋予相同的权限,那么你必须创建两份控制条目(每个vhost一份)。我们来动手创建一个访问控制条目。

     在这个例子里,假设你有名为sycamore的vhost,你想要授予cashing-tier完全的访问权限(配置,写和读权限)。你需要rabbitmqctl的set_permissions命令来完成:

# rabbitmqctl set_permissions -p sycamore cashing-tier ".*" ".*" ".*"
Setting permissions for user "cashing-tier" in vhost "sycamore" ...

     让我们把set_permissions命令分解开来,一块块分开看:

  •    -p sycamore -------------- 这告诉了set_permissions条目应该应用到哪个vhost上。
  •   cashing-tier --------------- 被授予权限的用户。
  •   ".*" ".*" ".*" ------------------ 这是授予的权限。这些值分别映射到配置,以及写和读。

  权限值是这个命令中最为有趣的部分。三个值中的每一个都是正则表达式。在这里,使用".*'指代所有权限(配置,以及写和读)。 ".*"意味着匹配任何队列或者交换器名字。这样就允许cashing-tier对任何队列或者交换器执行配置,写和读命令了。另一个例子可能会解释得更清楚。

  假设你为cashing-tier授予在oak vhost上的权限。你想要允许该用户对任何队列或者交换器可执行读操作,同时限制其只能对名字以checks-开始的队列和交换器允许写操作。同时,你想要完全阻止配置操作。为达到目的,你需要设计3个正则表达式:

  •   “.*"匹配任何队列或者交换器
  •   "checks-.*"只匹配名字以"checks-"开头的队列和交换器
  •   ""不匹配队列和交换器(这就是如何对用户拒绝指定的权限)

  把所有整合起来,像这样执行set_permissions:

 # rabbitmqctl set_permissions -p oak cashing-tier "" "checks-.*" ".*"
Setting permissions for user "cashing-tier" in vhost "oak" ...

  你可以通过list_permissions来验证权限是否赋予给了oak vhost:

# rabbitmqctl set_permissions -p oak cashing-tier "" "checks-.*" ".*"

  如果想要删除权限,可以使用clear_permissions命令移除用户在一个vhost上的权限:

# rabbitmqctl clear_permissions -p oak cashing-tier
Clearing permissions for user "cashing-tier" in vhost "oak" ...

# rabbitmqctl list_permissions -p oak  Listing permissions in vhost "oak" ...


  值得注意的是,clear_permissions会移除用户在指定vhost上的所有权限。如果你只是想要修改权限,只需用新权限执行set_permissions即可。如果你想要查看用户在所有vhost上的权限,可以使用list_user_permissions命令:

# rabbitmqctl list_user_permissions cashing-tier
Listing permissions for user "cashing-tier" ...
sycamore        .*      .*      .*


   RabbitMQ的权限创建非常容易且灵活。这种灵活性允许你为vhost创建复杂的权限结构。当你需要的时候,你会从中收益;但是如果你把它们设置得非常复杂的话,它们就很难理解。如果可能的话,尽量使用vhost分隔作为你的主要手段来确保应用程序的安全,并最小化每个vhost的访问控制条目。这样会帮助你避免难以调试的意外权限行为。

  现在你能够连接并确保Rabbit服务器的安全,你也许想看看服务器内部到底发生了什么。也许你需要知道有多少条资源调配消息在用户创建队列中。也许你想知道交换器是否存在于正确的vhost上。一个健康的RabbitMQ服务器的最重要的组成部分之一就是能够监控其内部状态。因此,下一节我们来看看如何检查自己的Rabbit服务器。

1 0