ace-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject svn commit: r814364 - in /websites/staging/ace/trunk/content: ./ dev-doc/design/ace-authentication.html dev-doc/design/auth_api.svg dev-doc/design/auth_connectionfactory.svg dev-doc/design/auth_main_components.svg
Date Wed, 25 Apr 2012 09:50:35 GMT
Author: buildbot
Date: Wed Apr 25 09:50:34 2012
New Revision: 814364

Staging update by buildbot for ace

    websites/staging/ace/trunk/content/dev-doc/design/auth_api.svg   (with props)
    websites/staging/ace/trunk/content/dev-doc/design/auth_connectionfactory.svg   (with props)
    websites/staging/ace/trunk/content/dev-doc/design/auth_main_components.svg   (with props)
    websites/staging/ace/trunk/content/   (props changed)

Propchange: websites/staging/ace/trunk/content/
--- cms:source-revision (original)
+++ cms:source-revision Wed Apr 25 09:50:34 2012
@@ -1 +1 @@

Added: websites/staging/ace/trunk/content/dev-doc/design/ace-authentication.html
--- websites/staging/ace/trunk/content/dev-doc/design/ace-authentication.html (added)
+++ websites/staging/ace/trunk/content/dev-doc/design/ace-authentication.html Wed Apr 25 09:50:34
@@ -0,0 +1,382 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="en">
+  <head>
+    <title></title>
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+    <meta property="og:image" content="" />
+    <link rel="stylesheet/less" type="text/css" href="/lib/bootstrap.less">
+    <link href="/css/prettify.css" rel="stylesheet">
+	<link href="/css/code.css" rel="stylesheet" media="screen">
+    <script src="/js/less-1.2.1.min.js" type="text/javascript"></script>
+    <script src=""></script>
+    <script src="/js/prettify.js"></script>
+    <script src="/js/bootstrap-alert.js"></script>
+    <script src="/js/bootstrap-dropdown.js"></script>
+    <script src="/js/bootstrap-tooltip.js"></script>
+    <script src="/js/bootstrap-alerts.js"></script>
+    <script src="/js/bootstrap-modal.js"></script>
+    <script src="/js/bootstrap-transition.js"></script>
+    <script src="/js/bootstrap-button.js"></script>
+    <script src="/js/bootstrap-popover.js"></script>
+    <script src="/js/bootstrap-twipsy.js"></script>
+    <script src="/js/bootstrap-buttons.js"></script>
+    <script src="/js/bootstrap-scrollspy.js"></script>
+    <script src="/js/bootstrap-typeahead.js"></script>
+    <script src="/js/bootstrap-carousel.js"></script>
+    <script src="/js/bootstrap-tab.js"></script>
+    <script src="/js/bootstrap-collapse.js"></script>
+    <script src="/js/bootstrap-tabs.js"></script>
+    <script>
+    $(function () { prettyPrint() })
+    $().dropdown()
+    </script>
+  </head>
+  <body style="padding-top: 50px;">
+    <div class="navbar navbar-fixed-top">
+      <div class="navbar-inner">
+        <div class="container">
+          <a class="brand" href="/index.html">Apache ACE</a>
+          <ul class="nav">
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">News <b class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/news.html">News</a>
+      </li>
+      <li>
+        <a href="/on-the-web.html">On the web</a>
+      </li>
+    </ul>
+  </li>
+  <li>
+    <a href="/downloads.html">Downloads</a>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">User Documentation <b
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/user-doc/introduction.html">Introduction</a>
+      </li>
+      <li>
+        <a href="/user-doc/getting-started.html">Getting Started</a>
+      </li>
+      <li>
+        <a href="/user-doc/features.html">Features</a>
+      </li>
+      <li>
+        <a href="/user-doc/faq.html">FAQ</a>
+      </li>
+      <li>
+        <a href="/user-doc/support.html">Support</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Developer Documentation
<b class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/dev-doc/requirements/">Requirements</a>
+      </li>
+      <li>
+        <a href="/dev-doc/architecture.html">Architecture</a>
+      </li>
+      <li>
+        <a href="/dev-doc/analysis/">Analysis</a>
+      </li>
+      <li>
+        <a href="/dev-doc/design/">Design</a>
+      </li>
+      <li>
+        <a href="/dev-doc/coding-standards.html">Coding Standards</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Get Involved <b class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="/get-involved/mailing-lists.html">Mailing Lists</a>
+      </li>
+      <li>
+        <a href="/get-involved/issue-tracking.html">Issue Tracking</a>
+      </li>
+      <li>
+        <a href="/get-involved/source-code.html">Source Code</a>
+      </li>
+      <li>
+        <a href="/get-involved/project-team.html">Project Team</a>
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Wiki <b class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="">Board
Reports <i class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="">Homepage <i
+      </li>
+    </ul>
+  </li>
+  <li class="dropdown">
+    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Apache <b class="caret"></b></a>
+    <ul class="dropdown-menu">
+      <li>
+        <a href="">Licenses <i class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="">Security <i class="icon-share-alt"></i></a>
+      </li>
+      <li>
+        <a href="">Sponsorship <i
+      </li>
+      <li>
+        <a href="">Thanks <i class="icon-share-alt"></i></a>
+      </li>
+    </ul>
+  </li>
+        </div>
+      </div>
+    </div>
+    <div class="container">
+      <p><a href="/"><i class='icon-home'></i> Home</a>&nbsp;&raquo&nbsp;<a
href="/dev-doc/">Dev-doc</a>&nbsp;&raquo&nbsp;<a href="/dev-doc/design/">Design</a></p>
+      <h1></h1>
+      <div class="clear"></div>
+      <div id="content"><p><em>Enabling authentication in ACE</em></p>
+<p>last updated: April 24th, 2012</p>
+<h2 id="introduction">Introduction</h2>
+<p>When provisioning software (partly) to targets, one has to rely upon the trustworthiness
of both the network and the target. Even if everything is under your control and governance,
one cannot entirely be sure that unwanted access takes place. A first step in order to prevent
unwanted access is <em>authentication</em>, which gives you the ability to verify
the identity of someone. Once the identity is known, one can apply <em>authentication</em>
in order to determine what actions are allowed and which are not.
+In this article, the recently added authentication layer of ACE is explained in more depth,
and some details on how extensions can be written for additional mechanisms are given. The
remainder of this article assumes the reader has basic knowledge of the principles behind
ACE, and has sufficient programming skills. For this article, the latest code of ACE (0.8.1-SNAPSHOT,
rev.1329269) was used.</p>
+<h2 id="communication-paths">Communication paths</h2>
+<p>Before going in more depth on the authentication layer of ACE, we first need to
pinpoint all places were authentication is to be applied. The following figure shows the main
components in ACE and their communication paths, providing a global overview of where authentication
is applicable to ACE.</p>
+<p><img alt="Figure 1: Overview of components and communication paths in ACE" src="auth_main_components.svg"
title="Figure 1: Overview of components and communication paths" /></p>
+<p>In figure 1, several communication paths exists (denoted by the circled digits):</p>
+<li>the client communicates to the server by means of both direct calls to its services
as well as remoted calls (by means of HTTP<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>);</li>
+<li>a management agent (representing the target) communicates to the management server
through HTTP calls;</li>
+<li>the REST API exposes the entire client API in a RESTful way. Communication to the
client occurs by both direct calls as well as through HTTP;</li>
+<li>the Vaadin Web UI exposes the entire client API as web application. Similar as
the REST API, it communicates both directly as through HTTP with the client.</li>
+<p>As can be seen from the above figure, most of the communication paths are based
on HTTP. The reason for this is twofold:</p>
+<li>It allows reuse of components; for example access to the OBR-servlet is used by
the both the client-API as well the web UI to upload new artifacts;</li>
+<li>it allows components to be deployed on different machines; for example, one does
not need to run the client on the same machine as the server. This could be useful for working
on high-latency networks.</li>
+<p>All direct communication paths do not need to be authenticated, as they require
that both caller and callee run in the same virtual machine, making it impossible to be used
outside the virtual machine<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup>.
Hence, we only need to add an authentication layer to the HTTP endpoints. However, adding
authentication to all HTTP endpoints poses us with the challenge to let the internal communication
paths that rely on HTTP to authenticate themselves as well. Not doing so would prevent ACE
from functioning correctly. A disadvantage of this approach is that it is an all-or-nothing
approach, either all users of the HTTP endpoints use authentication, or none of them. However,
the way users authenticate themselves can be different, meaning that one set of users can
use HTTP basic authentication to identify themselves, while another set uses client certificates
to identify themselves.</p>
+<h2 id="authentication-design">Authentication design</h2>
+<p>The high-level design for security in ACE is explained in the <a href="/dev-doc/design/remote-interfaces.html">remote
interface design</a>. From this design, we can derive several requirements for the design
of ACE's authentication layer:</p>
+<li>should be applicable and configurable for all remoted endpoints. If a new endpoint
is added to ACE, it should be easy to add and configure authentication for it;</li>
+<li>should be optional. If no authentication is desired, one should be able to remove
its services from the ACE distribution;</li>
+<li>should be pluggable. Various ways of authentication exist, and new ones can emerge.
Making the authentication mechanism pluggable allows new ways of authentication to be used
+<p>Based on these requirements, the design of the authentication layer is represented
in the following figure:</p>
+<p><img alt="Figure 2: Authentication layer class diagram" src="auth_api.svg" title="Figure
2: Authentication layer class diagram" /></p>
+<p>The <code>AuthenticationService</code> is responsible for authenticating
a user based on some piece of information. This piece of information can be a username/password
combination, a <code>HttpServletRequest</code> containing authentication request
headers, or any other set of information capable of uniquely identifying a user. The actual
authentication itself is delegated to one or more <code>AuthenticationProcessor</code>s,
which know how to handle  a given set of information (e.g., <code>HttpServletRequest</code>)
and can map this information to a particular user. In more detail, the calling sequence of
<code>AuthenticationService#authenticate</code> would be:</p>
+<li><code>AuthenticationService#authenticate</code> is called with a blob
of data, for example the <code>HttpServletRequest</code>;</li>
+<li>for each known <code>AuthenticationProcessor</code>:<ul>
+<li><code>AuthenticationProcessor#canHandle</code> is called with that
blob of data. An authentication processor can decide whether the given blob is something it
can handle or not;</li>
+<li>if it can be handled, the <code>AuthenticationProcessor#authenticate</code>
is called with that blob of data, along with an instance of the UserAdmin service. The authentication
processor is now responsible for converting the blob of data to an authenticated user, if
+<li>if a <code>User</code> object is returned from the authentication service<sup
id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup>, the authentication
phase will be regarded as successful. If <em>no</em> <code>User</code>
object is returned, the authentication phase will be regarded unsuccessful.</li>
+<p>This is only half the story for authentication. As stated before, ACE internally
also communicates through HTTP to access certain services. Without any changes, all those
remote calls will fail due to missing credentials. If we want to leave those means of communications
as-is, we would need to track down all places where remote calls are being made and inject
the proper credentials at those places. However, doing this is not only <em>very</em>
invasive and error prone but also not very developer friendly from a service-oriented perspective.
Alternatively, we could try to include the credentials in the URL itself, making it self-contained.
Not only would this approach limit our ability to use any kind of authentication mechanism
(it only works for username/password combos), it also required us to supply the credentials
manually each and every time we want to create a remote connection. Instead, we would like
to refrain from passing around credentials, and leverage the ser
 vice oriented aspects of OSGi to create remote connections for us. This service could then
be responsible for adding the right credentials for us, leaving the calling party totally
unaware about the fact authentication might be used. Such a service is denoted in the following
+<p><img alt="Figure 3: Connection Factory class diagram" src="auth_connectionfactory.svg"
title="Figure 3: Connection Factory class diagram" /></p>
+<p>The <code>ConnectionFactory</code> is responsible for creating <code>URLConnection</code>s,
given a "plain" URL. So, instead of calling <code>URL#openConnection()</code>
or <code>URL#openStream()</code>, we'll now have to call <code>ConnectionFactory#createConnection(url)</code>
instead. But, what advantage does this bring us? In order to allow the connection factory
to supply the credentials to <code>URLConnection</code>s, it is also registered
as <code>ManagedServiceFactory</code> that enables us to provide multiple configurations
of which credentials should be supplied to what (sets of) URLs. The introduction of the connection
factory allows us to abstract the creation of a connection and passing of credentials to it
from the URL. Internally, the connection factory will match each URL given in <code>createConnection</code>
with the URLs it is configured with. If a matching URL is found, it will use the credentials
in that configuration to supply to the <code>URLConnect
+<p>We've now closed the circle: we not only have defined how remote endpoints can apply
authentication, but also how all calling parties can remain using these remote endpoints without
having to be aware of authentication. </p>
+<h2 id="configuring-authentication">Configuring authentication</h2>
+<p>Before continuing on the details of configuring authentication for ACE, we first
identify what remote services are available, and how they can be configured.</p>
+<h3 id="remote-services">Remote services</h3>
+<p>All remote services in ACE are configurable with respect to the endpoint they can
be accessed. The following table shows an overview of the remote services, including the default
endpoint they use:</p>
+<th>Default endpoint</th>
+<th>Configuration PID</th>
+<td>provides access to the OBR (bundle repository) of ACE</td>
+<td>handles the actual provisioning of deployment packages to a target</td>
+<td>allows any number of logs for a target to be synchronized and accessed</td>
+<td><code>/auditlog</code><sup id="fnref:4"><a href="#fn:4" rel="footnote">4</a></sup></td>
this is a configuration factory!</strong></td>
+<td>provides access to the various (artifact/feature/distribution/target) internal
repositories of ACE</td>
+<td>allows <em>relay nodes</em> to replicate the internal repositories
of ACE</td>
+<td>provides the RESTful interface to ACE</td>
+<td>provides the Vaadin web interface</td>
+<h3 id="configuring-authentication-for-remote-services">Configuring authentication
for remote services</h3>
+<p>In the section on the design of the authentication layer, we've mentioned that if
a remote service wants to make use of authentication, it can make use of the <code>AuthenticationService</code>.
However, one of the design requirements was that authentication should be optional as well.
In order to enable or disable authentication, each remote service needs to do the following:</p>
+<li>add a <strong>mandatory</strong> configuration property <code>authentication.enabled
= false|true</code> to their configuration. Although any kind of name for this configuration
property can be used, it is <em>strongly</em> advised to stick to the same name
for all services;</li>
+<li>when the configuration of a remote service is updated, it should add a service
dependency to the <code>AuthenticationService</code>. By making this service <em>required</em>
when authentication is enabled, and <em>optional</em> when authentication is disabled,
we can adhere to the requirement of optionality for authentication;</li>
+<li>in case authentication is <em>enabled</em>, each request the service
obtains needs to be passed to the <code>AuthenticationService</code> first, and
depending on its outcome, the request can continue or not.</li>
+<p>To make this more concrete, an example of how the <code>BundleServlet</code>
is to be configured:</p>
+<h4 id="service-configuration">Service configuration</h4>
+<p>The service configuration, located in <code>org.apache.ace.obr.servlet.cfg</code>,
looks like:</p>
+<div class="codehilite"><pre><span class="c1"># Endpoint for this servlet</span>
+<span class="n">org</span><span class="o">.</span><span class="n">apache</span><span
class="o">.</span><span class="n">ace</span><span class="o">.</span><span
class="n">server</span><span class="o">.</span><span class="n">servlet</span><span
class="o">.</span><span class="n">endpoint</span><span class="o">=/</span><span
+<span class="c1"># Whether or not authentication is to be used</span>
+<span class="n">authentication</span><span class="o">.</span><span
class="n">enabled</span> <span class="o">=</span> <span class="n">true</span>
+<p>In <code>BundleServlet</code> we add the following code:</p>
+<div class="codehilite"><pre><span class="n">private</span> <span
class="n">volatile</span> <span class="n">boolean</span> <span class="n">m_useAuth</span><span
+<span class="n">private</span> <span class="n">volatile</span> <span
class="n">AuthenticationService</span> <span class="n">m_authService</span><span
+<span class="sr">//</span> <span class="o">...</span>
+<span class="n">public</span> <span class="n">void</span> <span
class="n">updated</span><span class="p">(</span><span class="n">Dictionary</span>
<span class="n">settings</span><span class="p">)</span> <span class="n">throws</span>
<span class="n">ConfigurationException</span> <span class="p">{</span>
+    <span class="k">if</span> <span class="p">(</span><span class="n">settings</span>
<span class="o">!=</span> <span class="n">null</span><span class="p">)</span>
<span class="p">{</span>
+        <span class="n">String</span> <span class="n">useAuthString</span>
<span class="o">=</span> <span class="p">(</span><span class="n">String</span><span
class="p">)</span> <span class="n">settings</span><span class="o">.</span><span
class="n">get</span><span class="p">(</span><span class="s">&quot;authentication.enabled&quot;</span><span
+        <span class="k">if</span> <span class="p">(</span><span
class="n">useAuthString</span> <span class="o">==</span> <span class="n">null</span>
<span class="o">||</span> <span class="o">!</span><span class="p">(</span><span
class="s">&quot;true&quot;</span><span class="o">.</span><span
class="n">equalsIgnoreCase</span><span class="p">(</span><span class="n">useAuthString</span><span
class="p">)</span> <span class="o">||</span> <span class="s">&quot;false&quot;</span><span
class="o">.</span><span class="n">equalsIgnoreCase</span><span class="p">(</span><span
class="n">useAuthString</span><span class="p">)))</span> <span class="p">{</span>
+            <span class="n">throw</span> <span class="k">new</span>
<span class="n">ConfigurationException</span><span class="p">(</span><span
class="s">&quot;authentication.enabled&quot;</span><span class="p">,</span>
<span class="s">&quot;Missing or invalid value!&quot;</span><span class="p">);</span>
+        <span class="p">}</span>
+        <span class="n">boolean</span> <span class="n">useAuth</span>
<span class="o">=</span> <span class="n">Boolean</span><span class="o">.</span><span
class="n">parseBoolean</span><span class="p">(</span><span class="n">useAuthString</span><span
+        <span class="n">m_useAuth</span> <span class="o">=</span>
<span class="n">useAuth</span><span class="p">;</span>
+    <span class="p">}</span>
+    <span class="k">else</span> <span class="p">{</span>
+        <span class="n">m_useAuth</span> <span class="o">=</span>
<span class="n">false</span><span class="p">;</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+<span class="sr">//</span> <span class="o">...</span>
+<span class="o">/**</span>
+ <span class="o">*</span> <span class="n">Called</span> <span
class="n">by</span> <span class="n">Dependency</span> <span class="n">Manager</span>
<span class="n">upon</span> <span class="n">initialization</span>
<span class="n">of</span> <span class="n">this</span> <span class="n">component</span><span
+ <span class="o">*/</span>
+<span class="n">protected</span> <span class="n">void</span> <span
class="n">init</span><span class="p">(</span><span class="n">Component</span>
<span class="n">comp</span><span class="p">)</span> <span class="p">{</span>
+    <span class="n">comp</span><span class="o">.</span><span class="n">add</span><span
class="p">(</span><span class="n">m_dm</span><span class="o">.</span><span
class="n">createServiceDependency</span><span class="p">()</span>
+        <span class="o">.</span><span class="n">setService</span><span
class="p">(</span><span class="n">AuthenticationService</span><span
class="o">.</span><span class="n">class</span><span class="p">)</span>
+        <span class="o">.</span><span class="n">setRequired</span><span
class="p">(</span><span class="n">m_useAuth</span><span class="p">)</span>
+        <span class="o">.</span><span class="n">setInstanceBound</span><span
class="p">(</span><span class="n">true</span><span class="p">)</span>
+        <span class="p">);</span>
+<span class="p">}</span>
+<p>As almost all of the services in ACE are managed by the Dependency Manager, we can
leverage its dynamics to inject our <code>BundleServlet</code> with an instance
of the <code>AuthenticationService</code> and provide us with a configuration<sup
id="fnref:5"><a href="#fn:5" rel="footnote">5</a></sup>. </p>
+<h4 id="implemention">Implemention</h4>
+<p>The actual authentication implementation itself is rather trivial: we simply intercept
all incoming requests in our servlet and verify whether it resolves to a valid user:</p>
+<div class="codehilite"><pre><span class="nv">@Override</span>
+<span class="n">protected</span> <span class="n">void</span> <span
class="n">service</span><span class="p">(</span><span class="n">HttpServletRequest</span>
<span class="n">req</span><span class="p">,</span> <span class="n">HttpServletResponse</span>
<span class="n">resp</span><span class="p">)</span> <span class="n">throws</span>
<span class="n">ServletException</span><span class="p">,</span> <span
class="n">IOException</span> <span class="p">{</span>
+    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span
class="n">authenticate</span><span class="p">(</span><span class="n">req</span><span
class="p">))</span> <span class="p">{</span>
+        <span class="sr">//</span> <span class="n">Authentication</span>
<span class="n">failed</span><span class="p">;</span> <span class="n">don</span><span
class="err">&#39;</span><span class="n">t</span> <span class="n">proceed</span>
<span class="n">with</span> <span class="n">the</span> <span class="n">original</span>
<span class="n">request</span><span class="o">...</span>
+        <span class="n">resp</span><span class="o">.</span><span
class="n">sendError</span><span class="p">(</span><span class="n">SC_UNAUTHORIZED</span><span
+    <span class="p">}</span> <span class="k">else</span> <span
+        <span class="sr">//</span> <span class="n">Authentication</span>
<span class="n">successful</span><span class="p">,</span> <span
class="n">proceed</span> <span class="n">with</span> <span class="n">original</span>
<span class="n">request</span><span class="o">...</span>
+        <span class="n">super</span><span class="o">.</span><span
class="n">service</span><span class="p">(</span><span class="n">req</span><span
class="p">,</span> <span class="n">resp</span><span class="p">);</span>
+    <span class="p">}</span>
+<span class="p">}</span>
+<span class="n">private</span> <span class="n">boolean</span> <span
class="n">authenticate</span><span class="p">(</span><span class="n">HttpServletRequest</span>
<span class="n">request</span><span class="p">)</span> <span class="p">{</span>
+    <span class="n">User</span> <span class="n">user</span> <span
class="o">=</span> <span class="n">null</span><span class="p">;</span>
+    <span class="k">if</span> <span class="p">(</span><span class="n">m_useAuth</span><span
class="p">)</span> <span class="p">{</span>
+        <span class="n">User</span> <span class="n">user</span> <span
class="o">=</span> <span class="n">m_authService</span><span class="o">.</span><span
class="n">authenticate</span><span class="p">(</span><span class="n">request</span><span
+    <span class="p">}</span>
+    <span class="k">if</span> <span class="p">(</span><span class="n">user</span>
<span class="o">==</span> <span class="n">null</span><span class="p">)</span>
<span class="p">{</span>
+        <span class="n">m_log</span><span class="o">.</span><span
class="nb">log</span><span class="p">(</span><span class="n">LogService</span><span
class="o">.</span><span class="n">LOG_INFO</span><span class="p">,</span>
<span class="s">&quot;Authentication failure!&quot;</span><span class="p">);</span>
+    <span class="p">}</span>
+    <span class="k">return</span> <span class="p">(</span><span
class="n">user</span> <span class="o">!=</span> <span class="n">null</span><span
+<span class="p">}</span>
+<p>Note that this implementation does not tell <em>how</em> the authentication
should occur, only that it should occur. How the authentication is performed, is determined
internally by the <code>AuthenticationService</code>, with the help of the registered
+<h3 id="configuring-the-connection-factory">Configuring the connection factory</h3>
+<p>Now that the remote service itself is no longer accepting unauthenticated requests,
we need to supply the credentials to access this service to the <code>ConnectionFactory</code>
service. This service can be configured using the PID <code>org.apache.ace.connectionfactory</code>
(<em>note that it is a configuration factory!</em>), which would result in the
following configuration for accessing our <code>BundleServlet</code>:</p>
+<div class="codehilite"><pre><span class="c1"># What kind of authentication
should we supply</span>
+<span class="n">authentication</span><span class="o">.</span><span
class="n">type</span> <span class="o">=</span> <span class="n">basic</span>
+<span class="c1"># The actual credentials for basic authentication</span>
+<span class="n">authentication</span><span class="o">.</span><span
class="n">user</span><span class="o">.</span><span class="n">name</span>
<span class="o">=</span> <span class="n">d</span>
+<span class="n">authentication</span><span class="o">.</span><span
class="n">user</span><span class="o">.</span><span class="n">password</span>
<span class="o">=</span> <span class="n">f</span>
+<span class="c1"># What is the base URL that these credentials apply to:</span>
+<span class="n">authentication</span><span class="o">.</span><span
class="n">baseURL</span> <span class="o">=</span> <span class="n">http:</span><span
class="sr">//</span><span class="n">localhost:8080</span><span class="sr">/obr/</span>
+<p>When this configuration is supplied to the <code>ConnectionFactory</code>,
it will provide a basic HTTP authentication header to each connection created for any URL
starting with "http://localhost:8080/obr/"<sup id="fnref:6"><a href="#fn:6" rel="footnote">6</a></sup>.
+<h3 id="configuring-the-management-agent">Configuring the management agent</h3>
+<div class="footnote">
+<hr />
+<li id="fn:1">
+<p>Other communication protocols could be used as well. However, currently, only HTTP
is natively supported by ACE. For the remainder of this article, we'll assume HTTP as protocol.&#160;<a
href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
+<li id="fn:2">
+<p>Assuming that all components in the management server are trusted and obtained from
trusted sources. If untrusted components would be allowed, we need to add authentication to
these communication paths as well.&#160;<a href="#fnref:2" rev="footnote" title="Jump
back to footnote 2 in the text">&#8617;</a></p>
+<li id="fn:3">
+<p>It is up to the implementation of <code>AuthenticationService</code>
whether the <em>first</em> found user is returned, or whether it checks if all
authentication processors yield the <em>same</em> user, or any other strategy
that is desired.&#160;<a href="#fnref:3" rev="footnote" title="Jump back to footnote
3 in the text">&#8617;</a></p>
+<li id="fn:4">
+<p>Amongst others, any number of log-endpoints can be defined, at least one is needed
for the audit log to be synchronized between target and management server.&#160;<a
href="#fnref:4" rev="footnote" title="Jump back to footnote 4 in the text">&#8617;</a></p>
+<li id="fn:5">
+<p>Note that we're using a configuration dependency for this service. This way, the
configuration <strong>must</strong> be present before the service itself is registered,
which allows us to determine if authentication should be used or not.&#160;<a href="#fnref:5"
rev="footnote" title="Jump back to footnote 5 in the text">&#8617;</a></p>
+<li id="fn:6">
+<p>Currently, a simple <code>String#startsWith()</code> is used to determine
whether or not a URL matches a configuration. This might change in the future when a more
sophisticated URL-matching strategy is needed.&#160;<a href="#fnref:6" rev="footnote"
title="Jump back to footnote 6 in the text">&#8617;</a></p>
+      <hr>
+      <footer>
+        <p>Copyright &#169; 2012 <a href="">The Apache
Software Foundation</a>, Licensed under the <a href="">Apache
License, Version 2.0</a>.<br/>Apache ACE, the Apache ACE logo, Apache and the
Apache feather logo are trademarks of The Apache Software Foundation. All other marks mentioned
may be trademarks or registered trademarks of their respective owners.</p>
+      </footer>
+    </div>
+  </body>

Added: websites/staging/ace/trunk/content/dev-doc/design/auth_api.svg
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/dev-doc/design/auth_api.svg
    svn:mime-type = image/svg+xml

Added: websites/staging/ace/trunk/content/dev-doc/design/auth_connectionfactory.svg
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/dev-doc/design/auth_connectionfactory.svg
    svn:mime-type = image/svg+xml

Added: websites/staging/ace/trunk/content/dev-doc/design/auth_main_components.svg
Binary file - no diff available.

Propchange: websites/staging/ace/trunk/content/dev-doc/design/auth_main_components.svg
    svn:mime-type = image/svg+xml

View raw message