summaryrefslogtreecommitdiff
path: root/documentation/content/xdocs/Qpid Design - Authentication.html
blob: da9d1b59130312f4750d3f2e40c57c1dfce956c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<html>
    <head>
        <title>Apache Qpid : Qpid Design - Authentication</title>
	    <link rel="stylesheet" href="styles/site.css" type="text/css" />
        <META http-equiv="Content-Type" content="text/html; charset=UTF-8">	    
    </head>

    <body>
	    <table class="pagecontent" border="0" cellpadding="0" cellspacing="0" width="100%" bgcolor="#ffffff">
		    <tr>
			    <td valign="top" class="pagebody">
				    <div class="pageheader">
					    <span class="pagetitle">
                            Apache Qpid : Qpid Design - Authentication
                                                    </span>
				    </div>
				    <div class="pagesubheading">
					    This page last changed on Jun 09, 2007 by <font color="#0050B2">rgreig</font>.
				    </div>

				    <h3><a name="QpidDesign-Authentication-Overview"></a>Overview</h3>

<p>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.</p>

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

<p>It is strongly recommended that any developer who needs to write a security provider or understand this in depth reads the <a href="http://java.sun.com/j2se/1.5.0/docs/guide/security/sasl/sasl-refguide.html" title="Visit page outside Confluence">SASL Guide</a> that is included with the JDK documentation.</p>

<h3><a name="QpidDesign-Authentication-PrincipalDatabases"></a>Principal Databases</h3>

<h5><a name="QpidDesign-Authentication-Classes"></a>Classes</h5>

<p>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.</p>

<p>The interface <tt>org.apache.qpid.server.security.auth.PrincipalDatabase</tt> must be implemented by any "user database". It contains a single method, which takes the <tt>Principal</tt> and the <tt>javax.security.auth.callback.PasswordCallback</tt> 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.</p>

<p>The only implementation currently provided is <tt>PasswordFilePrincipalDatabase</tt>. 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.</p>

<h5><a name="QpidDesign-Authentication-Configuration"></a>Configuration</h5>

<p>Clearly different databases will potentially require different configuration options. For example the <tt>PasswordFilePrincipalDatabase</tt> 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).</p>

<p>Configuration is specified in the configuration file like this:</p>
<div class="code" style="border-style: solid; "><div class="codeHeader" style="border-bottom-style: solid; "><b>config.xml</b></div><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;security&gt;</span>
    <span class="code-tag">&lt;principal-databases&gt;</span>
        <span class="code-tag">&lt;principal-database&gt;</span>
            <span class="code-tag">&lt;name&gt;</span>passwordfile<span class="code-tag">&lt;/name&gt;</span>
            <span class="code-tag">&lt;class&gt;</span>org.apache.qpid.server.security.auth.PasswordFilePrincipalDatabase<span class="code-tag">&lt;/class&gt;</span>
            <span class="code-tag">&lt;attributes&gt;</span>
                <span class="code-tag">&lt;attribute&gt;</span>
                    <span class="code-tag">&lt;name&gt;</span>passwordFile<span class="code-tag">&lt;/name&gt;</span>
                    <span class="code-tag">&lt;value&gt;</span>broker/etc/passwd<span class="code-tag">&lt;/value&gt;</span>
                <span class="code-tag">&lt;/attribute&gt;</span>
            <span class="code-tag">&lt;/attributes&gt;</span>
        <span class="code-tag">&lt;/principal-database&gt;</span>
    <span class="code-tag">&lt;/principal-databases&gt;</span>
<span class="code-tag">&lt;/security&gt;</span></pre>
</div></div>
<p>After instantiating the class specified by the <tt>class</tt> element, for each <tt>attribute</tt> 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 <tt>setPasswordFile(String arg)</tt> is invoked.</p>

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

<h3><a name="QpidDesign-Authentication-AuthenticationProviders"></a>Authentication Providers</h3>

<p>The authentication process as described in the AMQ protocol specification is as follows:</p>
<ol>
	<li>Broker sends list of authentication mechanisms to the client, in order of preference</li>
	<li>Client responds with chosen mechanism plus any initial response</li>
	<li>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).</li>
</ol>


<p>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).</p>

<h5><a name="QpidDesign-Authentication-AuthenticationProviderInitialiser"></a>AuthenticationProviderInitialiser</h5>

<p>The <tt>org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser</tt> 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.</p>

<h5><a name="QpidDesign-Authentication-Configuration"></a>Configuration</h5>

<p>The following example section from the configuration file illustrates how it might be used:</p>
<div class="code" style="border-style: solid; "><div class="codeHeader" style="border-bottom-style: solid; "><b>config.xml</b></div><div class="codeContent">
<pre class="code-xml"><span class="code-tag">&lt;sasl&gt;</span>
    <span class="code-tag">&lt;mechanisms&gt;</span>
        <span class="code-tag">&lt;mechanism&gt;</span>
            <span class="code-tag">&lt;initialiser&gt;</span>
                <span class="code-tag">&lt;class&gt;</span>org.apache.qpid.server.security.auth.CRAMMD5Initialiser<span class="code-tag">&lt;/class&gt;</span>
                <span class="code-tag">&lt;principal-database&gt;</span>passwordfile<span class="code-tag">&lt;/principal-database&gt;</span>
            <span class="code-tag">&lt;/initialiser&gt;</span>
        <span class="code-tag">&lt;/mechanism&gt;</span>
        <span class="code-tag">&lt;mechanism&gt;</span>
            <span class="code-tag">&lt;initialiser&gt;</span>
                <span class="code-tag">&lt;class&gt;</span>org.apache.qpid.server.security.auth.amqplain.AmqPlainInitialiser<span class="code-tag">&lt;/class&gt;</span>
                <span class="code-tag">&lt;principal-database&gt;</span>passwordfile<span class="code-tag">&lt;/principal-database&gt;</span>
            <span class="code-tag">&lt;/initialiser&gt;</span>
        <span class="code-tag">&lt;/mechanism&gt;</span>
    <span class="code-tag">&lt;/mechanisms&gt;</span>
<span class="code-tag">&lt;/sasl&gt;</span></pre>
</div></div>
<p>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.</p>

<h5><a name="QpidDesign-Authentication-CallbackHandlers"></a>CallbackHandlers</h5>

<p>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 <tt>getCallbackHandler</tt> in the <tt>AuthenticationProviderInitialiser</tt> class must return the appropriate handler for the mechanism.</p>

<h5><a name="QpidDesign-Authentication-AuthenticationProviderInitialiserConfiguration"></a>AuthenticationProviderInitialiser Configuration</h5>

<p>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.</p>

<h3><a name="QpidDesign-Authentication-ClientAuthentication"></a>Client Authentication</h3>

<p>Client authentication is similar although it is made simpler by the fact that there is no need for a <tt>PrincipalDatabase</tt>. 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.</p>

<h5><a name="QpidDesign-Authentication-CallbackHandlerRegistry"></a>CallbackHandlerRegistry</h5>

<p>The most important things needed on the client are:</p>
<ol>
	<li>a way to specify which SASL mechanisms we want to use, in order of preference</li>
	<li>a way to associate a callback handler with a mechanism (remember that different mechanisms require or support different callbacks)</li>
</ol>


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

<p><tt>AMQCallbackHandler</tt> extends <tt>javax.security.auth.CallbackHandler</tt> 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 <tt>AMQProtocolSession</tt> and by extension from the <tt>javax.jms.Connection</tt>. The obvious example is the username and password.</p>

<p>To specify callback handlers a property file is used. The default property contains this:</p>
<div class="code"><div class="codeContent">
<pre class="code-java">CallbackHandler.CRAM-MD5=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
CallbackHandler.AMQPLAIN=org.apache.qpid.client.security.UsernamePasswordCallbackHandler</pre>
</div></div>
<p>The default callbackhandler registry initialises handlers for CRAM-MD5 and AMQPLAIN. To specify your own propertyfile use the java system property <tt>amq.callbackhandler.properties</tt>.</p>

<h5><a name="QpidDesign-Authentication-DynamicSaslRegistrar"></a>DynamicSaslRegistrar</h5>

<p>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 <tt>AMQCallbackHandler</tt>. 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 <tt>DynamicSaslRegistrar</tt> which does this.</p>

<p>To configure Sasl providers, you need to create a properties file in this format:</p>
<div class="code"><div class="codeContent">
<pre class="code-java">AMQPLAIN=org.apache.qpid.client.security.amqplain.AmqPlainSaslClientFactory</pre>
</div></div>
<p>The key is the mechanism name and the value is the Sasl client factory (which must implement <tt>javax.security.sasl.SaslClientFactory</tt>).</p>

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

				    
                    			    </td>
		    </tr>
	    </table>
	    <table border="0" cellpadding="0" cellspacing="0" width="100%">
			<tr>
				<td height="12" background="border/border_bottom.gif"><img src="border/spacer.gif" width="1" height="1" border="0"/></td>
			</tr>
		    <tr>
			    <td align="center"><font color="grey">Document generated by Confluence on Apr 22, 2008 02:47</font></td>
		    </tr>
	    </table>
    </body>
</html>