Authorization

After a client is successfully authenticated by the message broker, it needs to perform some activities in some virtual hosts. In the earlier chapters, we saw that permissions are defined per vhost and live either internally in the message broker or externally. The RabbitMQ LDAP backend plugin that we saw earlier provides you with an ability to store permissions in an LDAP server. The following types of permissions are configured in the message broker:

  • configure: This allows a resource to be created, modified, or deleted
  • write: This allows a resource to be written to
  • read: This allows a resource to be read from

We already discussed how to manage permissions using the rabbitmqctl utility and the HTTP API. The following commands can be used from the utility to manage permissions:

  • set_permissions: This sets permissions per user per vhost
  • clear_permissions: This clears permissions per user per vhost
  • list_permissions: This lists the users that are granted access to a particular vhost along with their permissions
  • list_user_permissions: This lists the permissions of a particular user

LDAP authentication

The LDAP user that we created earlier by default has all the permissions to the broker (except for being an administrator). Let's suppose that we want to disable the configure permissions, allow more fine-grained write permissions only to certain queues (in certain vhosts), or make it an administrator. The RabbitMQ LDAP provides a query mechanism to check permissions as configured in the LDAP server. There are three types of queries that can be specified in the RabbitMQ configuration and further contain different types of subqueries that are executed against the LDAP server:

  • vhost_access_query: As users and permissions must be checked against vhosts that must be created in RabbitMQ, we can define vhost entries in the LDAP server against which to check for available permissions and tags. In fact, these entries represent a subset of the existing vhosts in the RabbitMQ server against which we check whether users have further access permissions or not. The default query is {constant, true}, which specifies that access to all vhosts is given to all the users (the constant queries are aliases for all, which return true or false for any value checked by vhost_access_query).
  • resource_access_query: These are the types of queries that allow you to check whether a user has specific permissions (read, write, or configure) for a particular vhost to which the user has access (as checked by vhost_access_query). The default is {constant, true}.
  • tag_queries: These are the types of queries that allow you to specify the tags that are given to particular users (such as management or administrator). The default is {administrator, {constant, false}}.

The types of subqueries that can be specified for each type of these queries use a simple DSL; you can review the LDAP RabbitMQ plugin documentation for an extensive list of all types of subqueries. We will specify the following access domains for our message broker:

  • The test user is the vhost
  • The guest user is an administrator and has access to the management console
  • The Martin user has access only to the test vhost and can publish to exchanges starting with the test_ prefix
  • The Subscriber user has access to the test vhost only and can read messages from queues starting with the test_ prefix

The following diagram specifies the LDAP structure of the organization:

LDAP authentication

Before we can implement this setup, we need to create the test vhost in RabbitMQ. The following example creates the test vhost using the rabbitmqctl utility:

rabbitmqctl add_vhost test

You also need to create LDAP entries for the guest and Subsciber users in the same manner that we created the entry for the user with the name Martin earlier. Here is a sample ldiff file (users.ldiff) for the two users:

## guest user
dn: cn=guest,ou=users,dc=example,dc=com
objectclass: inetOrgPerson
cn: guest
sn: guest
uid: guest
mail: [email protected]

## Subscriber user
dn: cn=Subscriber,ou=users,dc=example,dc=com
objectclass: inetOrgPerson
cn: Subscriber
sn: Subscriber
uid: Subscriber
mail: [email protected]

To import the preceding ldiff file and set a password for the users, you can execute the following set of commands:

ldapadd -x -D "cn=organization,dc=example,dc=com" -W –f users.ldiff
ldappasswd -D "cn=organization,dc=example,dc=com" "cn=guest,ou=users,dc=example,dc=com" –W –S
ldappasswd -D "cn=organization,dc=example,dc=com" "cn=Subscriber,ou=users,dc=example,dc=com" –W –S

Finally, we need to create the vhosts group along with an entry for the test vhost (vhosts.ldiff):

## Example.com vhosts
dn: ou=vhosts,dc=example,dc=com
ou: vhosts
description: Vhosts in the organization
objectClass: organizationalUnit

## test vhost
dn: cn=test,ou=vhosts,dc=example,dc=com
objectclass: organizationalRole
description: test vhost

Execute the following in order to import the preceding entries:

ldapadd -x -D "cn=organization,dc=example,dc=com" -W –f vhosts.ldiff

Note that we are using a predefined object class (organizationalRole) for the vhost entry in LDAP. You can prefer to create your own object class for the purpose of describing a vhost along with its attributes in your organization. Finally, we need to specify the proper queries for permission checking in the LDAP configuration (as part of the rabbitmq_auth_backend_ldap section in your RabbitMQ configuration file):

{vhost_access_query,    {exists, "cn=${vhost},ou=vhosts,dc=example,dc=com"}},
{resource_access_query,
   {for, [ 
    {permission, configure, {match, 
{string, "${username}"},{string, "guest"}}},
    {permission, write, {'and', [
	{match, {string, "${username}"},{string, "(Martin|guest"}},
	{match, {string, "${name}"},{string, "test_*"}}]} },
    {permission, read, {'and', [
	{match, {string, "${username}"},{string, "(Subscriber|guest)"}},
	{match, {string, "${name}"},{string, "test_*"}}]} }
    ] }},
{tag_queries, [{administrator, {match, {string, "${username}"},{string, "guest"}}},
               {management,    {constant, true}}]}

The preceding configuration is easy to understand, but it might turn out to be clumsy to write and test. After it is added to the configuration file, you can try to log in with the guest/guest user and check whether it has administrative access. You can try to create an object using the Subscriber user or send/receive messages using the Martin/Subscriber user. In practice, the preceding configuration should be designed carefully based on the organizational LDAP schema in order to prevent security holes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.10.45