Overview

The AMQ Protocol specifies that SASL is used to exchange authentication information. However, SASL on its own is only a small part of any authentication solution.

QPID provides an authentication framework based on SASL, that provides the ability to plug in arbitrary user (or more strictly principal) databases and different SASL-compliant mechanisms. This section describes how to configure both the client and broker and how to add new providers.

It is strongly recommended that any developer who needs to write a security provider or understand this in depth reads the SASL Guide that is included with the JDK documentation.

Principal Databases

NEEDS REVISION
NOTE : This documentation is outdated as of M2.

Classes

Ignoring the exchange of credentials, a key thing that needs to be done is validate that the credentials are valid. The simple example is checking the username and password match those in a password file.

The interface org.apache.qpid.server.security.auth.PrincipalDatabase must be implemented by any "user database". It contains a single method, which takes the Principal and the javax.security.auth.callback.PasswordCallback that wants to receive the password. This might seem odd, since the obvious approach would be a store that took a principal and some credentials and returned a true or false indicating whether the credentials are valid. However, this approach is required to fit in with the SASL APIs which use callbacks exclusively.

The only implementation currently provided is PasswordFilePrincipalDatabase. This expects to read password from a file which is in the format username:password where the password is in plaintext and a carriage return separates each username and password pair.

Configuration

Clearly different databases will potentially require different configuration options. For example the PasswordFilePrincipalDatabase needs to be configured with the location of a password file whereas a Kerberos realm database would need to know the location of a keytab file (for example).

Configuration is specified in the configuration file like this:

config.xml
<security>
    <principal-databases>
        <principal-database>
            <name>passwordfile</name>
            <class>org.apache.qpid.server.security.auth.PasswordFilePrincipalDatabase</class>
            <attributes>
                <attribute>
                    <name>passwordFile</name>
                    <value>broker/etc/passwd</value>
                </attribute>
            </attributes>
        </principal-database>
    </principal-databases>
</security>

After instantiating the class specified by the class element, for each attribute an attempt is made to invoke a setter method with value passed in as an argument. In the above example, the method with signature void setPasswordFile(String arg) is invoked.

The name element is significant and must be unique. The name is passed as an argument to the SASL provider implementations (described below).

Authentication Providers

The authentication process as described in the AMQ protocol specification is as follows:

  1. Broker sends list of authentication mechanisms to the client, in order of preference
  2. Client responds with chosen mechanism plus any initial response
  3. Broker evaluates response and determines whether authentication has succeeded. If authentication is not yet complete, another set of challenge/responses takes place until authentication is completed (with either success or failure).

The broker configuration allows the administrator to configure the set of supported authentication mechanisms and the principal database used by each mechanism. It also allows the dynamic registration of additional SASL providers (this avoids the need to modify the JRE configuration).

AuthenticationProviderInitialiser

The org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser interface must be implemented for each mechanism. Note this includes the SASL mechanisms that are supported by default by the JRE (e.g. CRAM-MD5). In particular, the interface allows arbitrary configuration (since each provider may have its own specialised configuration requirements), the specification of a callback handler and a factory class for JCA registration.

Configuration

The following example section from the configuration file illustrates how it might be used:

config.xml
<sasl>
    <mechanisms>
        <mechanism>
            <initialiser>
                <class>org.apache.qpid.server.security.auth.CRAMMD5Initialiser</class>
                <principal-database>passwordfile</principal-database>
            </initialiser>
        </mechanism>
        <mechanism>
            <initialiser>
                <class>org.apache.qpid.server.security.auth.amqplain.AmqPlainInitialiser</class>
                <principal-database>passwordfile</principal-database>
            </initialiser>
        </mechanism>
    </mechanisms>
</sasl>

The above section defines two authentication mechanisms: CRAM-MD5 and AMQPLAIN. Since CRAM-MD5 appears first it will appear on the list of mechanisms offered to the client first. Both mechanisms are configured to use the principal database named "passwordfile" which must be defined in the appropriate section in the config file.

CallbackHandlers

Each SASL provider works with CallbackHandlers. This enables the provider to obtain information (e.g. the password) from the application as well as set the result of authentication (such as the canonical name of the principal just authenticed). The particular CallbackHandlers vary depending on the mechanism being used. The method getCallbackHandler in the AuthenticationProviderInitialiser class must return the appropriate handler for the mechanism.

AuthenticationProviderInitialiser Configuration

Since the initialisation of an authentication provider will require potentially arbitrary configuration, the interface supplies to the initialiser the Configuration object as well as the base path into the configuration file so that the initialiser can look for arbitrary configuration elements.

Client Authentication

Client authentication is similar although it is made simpler by the fact that there is no need for a PrincipalDatabase. Since we do not use any heavyweight configuration mechanism (such as the Apache Commons Configuration used by the broker) on the client side, we also need an alternative way to configure providers.

CallbackHandlerRegistry

The most important things needed on the client are:

  1. a way to specify which SASL mechanisms we want to use, in order of preference
  2. a way to associate a callback handler with a mechanism (remember that different mechanisms require or support different callbacks)

The CallbackHandlerRegistry provides a way to do this. Using a properties file to provide the configuration information, it maps from mechanisms to AMQCallbackHandler instances.

AMQCallbackHandler extends javax.security.auth.CallbackHandler and only adds one method, which associates a protocol session with a callback handler. This enables the callback handler to retrieve any specific information from the AMQProtocolSession and by extension from the javax.jms.Connection. The obvious example is the username and password.

To specify callback handlers a property file is used. The default property contains this:

CallbackHandler.CRAM-MD5=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
CallbackHandler.AMQPLAIN=org.apache.qpid.client.security.UsernamePasswordCallbackHandler

The default callbackhandler registry initialises handlers for CRAM-MD5 and AMQPLAIN. To specify your own propertyfile use the java system property amq.callbackhandler.properties.

DynamicSaslRegistrar

For SASL providers that are part of the JRE or have been added manually to the JRE security configuration all that is required is the creation of an AMQCallbackHandler. However, if you need to use a custom SASL provider it needs to be registered with JCA. Rather than place the burden for doing this on the application developer, we provide a DynamicSaslRegistrar which does this.

To configure Sasl providers, you need to create a properties file in this format:

AMQPLAIN=org.apache.qpid.client.security.amqplain.AmqPlainSaslClientFactory

The key is the mechanism name and the value is the Sasl client factory (which must implement javax.security.sasl.SaslClientFactory).

The default properties file registers only the AMQPLAIN mechanism; you can specify a custom property file using the system property amq.dynamicsaslregistrar.properties.

  • No labels