2

I'm trying to get LDAP authentication/authorization working with RabbitMQ 3.6.2 on Windows 7. I've gotten basic authentication working where the application sends a username/password, but the password is in the code which I need to figure out how to avoid. Has anyone achieved success in configuring RabbitMQ to authenticate via LDAP without supplying a password? I've been referring to the LDAP plugin docs, but to no avail.

My rabbitmq.config file is set up thusly:

[
    {rabbit, 
        {auth_backends, [{rabbit_auth_backend_ldap, rabbit_auth_backend_internal},
                                                     rabbit_auth_backend_internal]}
    },
    {rabbitmq_auth_backend_ldap,
        [{servers, ["theserver.thedomain.com"]},
        %% this works, but a password is still required
        {user_dn_pattern, "CN=${username},OU=theADgroup,OU=anothergroup,DC=thedomain,DC=dom"},
        %% looks like this is required
        {other_bind, anon},
        {use_ssl, false},
        {port, 389},
        {log, true}
    ]}
].

Thanks,

Andy

Andy
  • 2,709
  • 5
  • 37
  • 64

1 Answers1

3

Here's what I ended up with in case it helps anyone. I had to add 3 parameters to the config:

  • dn_lookup_attribute set to "userPrincipalName"
  • dn_lookup_base set to "DC=Name1,DC=Name2" (change this to fit your AD setup)
  • user_dn_pattern set to "${username}@thedomain.com" (this was done for convenience - without this, users had to log in with their full email address, but with it, they only have to use their username)

You likely won't need all the settings in the config below, but this is my config nonetheless including authenticating over SSL and granting certain specific AD groups "Administrator" access to RabbitMQ Management UI. I added lots of comments to hopefully aid in figuring it out.

[
    {rabbit, 
        {auth_backends, [{rabbit_auth_backend_ldap, rabbit_auth_backend_internal}]}
    },
    %% LDAP Authentication.  See https://www.rabbitmq.com/ldap.html
    {rabbitmq_auth_backend_ldap,
        [{servers, ["theserver.thedomain.com"]},
        {dn_lookup_attribute, "userPrincipalName"},
        {dn_lookup_base, "DC=Name1,DC=Name2"},
        %% this makes it so that login usernames are just <username> instead of <username>@thedomain.com
        {user_dn_pattern, "${username}@thedomain.com"},
        %% Authenticate over SSL
        {use_ssl, true},
        {port, 636},
        %% Change this to true to troubleshoot LDAP failures (see file rabbit@<machinename>.log and scroll to bottom for the most recent activity)
        {log, false},

        %% ------------------------------------------------------------------------------------
        %% LDAP-based authorization for employee logins to the management UI.
        %% The following settings maps the permissions that LDAP-authenticated users will have.
        %% For more info, see: https://www.rabbitmq.com/access-control.html
        %% ------------------------------------------------------------------------------------

        %% Grant access to all virtual hosts (this is the default, but is present here for the sake of transparency)
        {vhost_access_query, {constant, true}},

        %% Grant access to "resources" (exchanges, queues, bindings, etc.) (this is the default)
        {resource_access_query, {constant, true}},

        %% Grant RabbitMQ administrator access based on LDAP group membership.
        {tag_queries, [{administrator, {'or',
            [{in_group, "CN=Group 1 Name,OU=Group 1 OU,OU=Groups,DC=thecompany,DC=com"},
            {in_group, "CN=Group 2 Name,OU=Group 2 OU,OU=Groups,DC=thecompany,DC=com"},
            {in_group_nested, "CN=Group 3 Name,OU=Group 3 OU,OU=Groups,DC=thecompany,DC=com"}]}
        }]}
    ]}
].

Edit: Here's a snippet from a program that shows RabbitMQ ConnectionFactory connecting without using username/password since it relies on certificate-based authentication. You only need the path to the SSL certificate (generated for free using OpenSSL) along with the certificate passphrase.

using LipsumGenerator.Message;
using Messaging.Work;
using RabbitMQ.Client;
using System;
using System.Configuration;
using System.Security.Authentication;

namespace Publisher
{
    class Program
    {
        static void Main(string[] args)
        {
            var factory = new ConnectionFactory();
            factory.HostName = ConfigurationManager.AppSettings["rabbitmqHostName"];

            factory.AuthMechanisms = new AuthMechanismFactory[] { new ExternalMechanismFactory() };
            factory.Ssl.ServerName = ConfigurationManager.AppSettings["rabbitmqServerName"];
            factory.Ssl.CertPath = ConfigurationManager.AppSettings["certificateFilePath"];
            factory.Ssl.CertPassphrase = ConfigurationManager.AppSettings["certificatePassphrase"];
            factory.Ssl.Enabled = true;
            factory.Ssl.Version = SslProtocols.Tls12;
            factory.Port = AmqpTcpEndpoint.DefaultAmqpSslPort;
            factory.VirtualHost = "/";

            using (var connection = factory.CreateConnection())
            {
                using (var channel = connection.CreateModel())
                {
                    Console.WriteLine(" [*] Publishing messages. To exit press CTRL+C");

                    int count = 0;
                    var rand = new Random();

                    while (true)
                    {
                        count++;
                        WorkProcessor.EnqueueMessage(channel, "Lipsum", new LipsumGeneratorMessage(rand.Next(5)));
                        Console.WriteLine("Sent message Lipsum " + count);
                        System.Threading.Thread.Sleep(rand.Next(2000));
                    }
                }
            }
        }
    }
}
Andy
  • 2,709
  • 5
  • 37
  • 64
  • Thanks for posting. What does your connection factory code look like? – innominate227 Jul 20 '17 at 02:51
  • I'm using a self-signed SSL certificate to authenticate to RabbitMQ, but that may be overkill for you. If you want to use SSL, please see this post here - I posted my answer in the question - but I figured out how to only use the certificate file + passphrase without any username/password. https://stackoverflow.com/questions/39642777/rabbitmq-c-sharp-ssl – Andy Jul 23 '17 at 14:11
  • 3
    I think you ended up doing something different than what I thought the original question on this post was asking. I was expecting a solution similar to how you can do HttpWebRequest.UseDefaultCredentials to authenticate with an IIS server set to use windows auth. It looks like your solution still requires either having the user type in a password, or putting it in a config file. – innominate227 Jul 24 '17 at 15:22
  • You don't need a username/password if you use certificate-based authentication. I've updated my answer to include the code that will work for you assuming that SSL is set up correctly (which is not a trivial task). – Andy Jul 25 '17 at 17:57
  • I think I’m sharing the same confusion as innominate227. Does your first solution still require the password to be stored? I’m looking at doing something similar and ideally would like to integrate with LDAP but not have to store the password in my application. Can Kerberos be used here maybe? Or is the cert really the only way to go? Thanks. – Tophat Gordon Sep 19 '18 at 20:33
  • The solution posted above requires a certificate passphrase (not the same as a password) to be provided to the ConnectionFactory. If you want to use LDAP instead of certificate-based authentication, this is a decent place to start, although there's no C# code provided to help: https://www.rabbitmq.com/ldap.html – Andy Sep 21 '18 at 14:58