Author: buildbot
Date: Wed Apr 25 12:57:45 2012
New Revision: 814394

Log:
Staging update by buildbot for ace

Modified:
    websites/staging/ace/trunk/content/   (props changed)
    websites/staging/ace/trunk/content/dev-doc/design/ace-authentication.html

Propchange: websites/staging/ace/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Apr 25 12:57:45 2012
@@ -1 +1 @@
-1330212
+1330254

Modified: 
websites/staging/ace/trunk/content/dev-doc/design/ace-authentication.html
==============================================================================
--- websites/staging/ace/trunk/content/dev-doc/design/ace-authentication.html 
(original)
+++ websites/staging/ace/trunk/content/dev-doc/design/ace-authentication.html 
Wed Apr 25 12:57:45 2012
@@ -153,13 +153,14 @@
       <h1></h1>
       <div class="clear"></div>
       <div id="content"><p><em>Enabling authentication in ACE</em></p>
-<p>last updated: April 24th, 2012</p>
+<p>last updated: April 25th, 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>authorization</em> in 
order to determine what actions are allowed and which are not.
+<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><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" /><br />
+Figure 1: Overview of components and communication paths.</p>
 <p>In figure 1, several communication paths exists (denoted by the circled 
digits):</p>
 <ol>
 <li>the client communicates to the ACE 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>
@@ -181,25 +182,27 @@ In this article, the recently added auth
 <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 easily.</li>
 </ol>
 <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>
-<ol>
-<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 possible.</li>
+<p><img alt="Figure 2: Authentication layer class diagram" src="auth_api.svg" 
title="Figure 2: Authentication layer class diagram" /><br />
+Figure 2: Authentication layer class diagram.</p>
+<p>The <tt>AuthenticationService</tt> is responsible for authenticating a user 
based on some piece of information. This piece of information can be a 
username/password combination, a <tt>HttpServletRequest</tt> 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 <tt>AuthenticationProcessor</tt>s, which know how to handle  a 
given set of information (e.g., <tt>HttpServletRequest</tt>) and can map this 
information to a particular user. In more detail, the calling sequence of 
<tt>AuthenticationService#authenticate</tt> would be:</p>
+<ol>
+<li><tt>AuthenticationService#authenticate</tt> is called with a blob of data, 
for example the <tt>HttpServletRequest</tt>;</li>
+<li>for each known <tt>AuthenticationProcessor</tt>:<ul>
+<li><tt>AuthenticationProcessor#canHandle</tt> 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 <tt>AuthenticationProcessor#authenticate</tt> 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 possible.</li>
 </ul>
 </li>
-<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>
+<li>if a <tt>User</tt> 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> <tt>User</tt> object is 
returned, the authentication phase will be regarded unsuccessful.</li>
 </ol>
 <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 figure:</p>
-<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
 ion</code>.</p>
+<p><img alt="Figure 3: Connection Factory class diagram" 
src="auth_connectionfactory.svg" title="Figure 3: Connection Factory class 
diagram" /><br />
+Figure 3: Connection Factory class diagram.</p>
+<p>The <tt>ConnectionFactory</tt> is responsible for creating 
<tt>URLConnection</tt>s, given a "plain" URL. So, instead of calling 
<tt>URL#openConnection()</tt> or <tt>URL#openStream()</tt>, we'll now have to 
call <tt>ConnectionFactory#createConnection(url)</tt> instead. But, what 
advantage does this bring us? In order to allow the connection factory to 
supply the credentials to <tt>URLConnection</tt>s, it is also registered as 
<tt>ManagedServiceFactory</tt> 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 <tt>createConnection</tt> 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 <tt>URLConnection</tt>.</p>
 <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 
through which they can be accessed. The following table shows an overview of 
the remote services, including the default endpoint they use:</p>
+<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>
 <table>
 <thead>
 <tr>
@@ -211,59 +214,59 @@ In this article, the recently added auth
 </thead>
 <tbody>
 <tr>
-<td><code>BundleServlet</code></td>
+<td><tt>BundleServlet</tt></td>
 <td>provides access to the OBR (bundle repository) of ACE</td>
-<td><code>/obr</code></td>
-<td><code>org.apache.ace.obr.servlet</code></td>
+<td><tt>/obr</tt></td>
+<td><tt>org.apache.ace.obr.servlet</tt></td>
 </tr>
 <tr>
-<td><code>DeploymentServlet</code></td>
+<td><tt>DeploymentServlet</tt></td>
 <td>handles the actual provisioning of deployment packages to a target</td>
-<td><code>/deployment</code></td>
-<td><code>org.apache.ace.deployment.servlet</code></td>
+<td><tt>/deployment</tt></td>
+<td><tt>org.apache.ace.deployment.servlet</tt></td>
 </tr>
 <tr>
-<td><code>LogServlet</code></td>
+<td><tt>LogServlet</tt></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>
-<td><code>org.apache.ace.server.log.servlet.factory</code><br/><strong>note: 
this is a configuration factory!</strong></td>
+<td><tt>/auditlog</tt><sup id="fnref:4"><a href="#fn:4" 
rel="footnote">4</a></sup></td>
+<td><tt>org.apache.ace.server.log.servlet.factory</tt><br/><strong>note: this 
is a configuration factory!</strong></td>
 </tr>
 <tr>
-<td><code>RepositoryServlet</code></td>
+<td><tt>RepositoryServlet</tt></td>
 <td>provides access to the various (artifact/feature/distribution/target) 
internal repositories of ACE</td>
-<td><code>/repository</code></td>
-<td><code>org.apache.ace.repository.servlet.RepositoryServlet</code></td>
+<td><tt>/repository</tt></td>
+<td><tt>org.apache.ace.repository.servlet.RepositoryServlet</tt></td>
 </tr>
 <tr>
-<td><code>RepositoryReplicationServlet</code></td>
+<td><tt>RepositoryReplicationServlet</tt></td>
 <td>allows <em>relay nodes</em> to replicate the internal repositories of 
ACE</td>
-<td><code>/replication</code></td>
-<td><code>org.apache.ace.repository.servlet.RepositoryReplicationServlet</code></td>
+<td><tt>/replication</tt></td>
+<td><tt>org.apache.ace.repository.servlet.RepositoryReplicationServlet</tt></td>
 </tr>
 <tr>
-<td><code>RESTClientServlet</code></td>
+<td><tt>RESTClientServlet</tt></td>
 <td>provides the RESTful interface to ACE</td>
-<td><code>/client</code></td>
-<td><code>org.apache.ace.client.rest</code></td>
+<td><tt>/client</tt></td>
+<td><tt>org.apache.ace.client.rest</tt></td>
 </tr>
 <tr>
-<td><code>VaadinServlet</code></td>
+<td><tt>VaadinServlet</tt></td>
 <td>provides the Vaadin web interface</td>
-<td><code>/ace</code></td>
-<td><code>org.apache.ace.webui.vaadin</code></td>
+<td><tt>/ace</tt></td>
+<td><tt>org.apache.ace.webui.vaadin</tt></td>
 </tr>
 </tbody>
 </table>
 <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>
+<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 <tt>AuthenticationService</tt>. 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>
 <ol>
 <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>
+<li>when the configuration of a remote service is updated, it should add a 
service dependency to the <tt>AuthenticationService</tt>. 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 <tt>AuthenticationService</tt> first, and 
depending on its outcome, the request can continue or not.</li>
 </ol>
-<p>To make this more concrete, an example of how the 
<code>BundleServlet</code> is to be configured:</p>
+<p>To make this more concrete, an example of how the <tt>BundleServlet</tt> 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>
+<p>The service configuration, located in 
<tt>org.apache.ace.obr.servlet.cfg</tt>, looks like:</p>
 <div class="codehilite"><pre><span class="c"># Endpoint for this servlet</span>
 <span class="na">org.apache.ace.server.servlet.endpoint</span><span 
class="o">=</span><span class="s">/obr</span>
 <span class="c"># Whether or not authentication is to be used</span>
@@ -271,7 +274,7 @@ In this article, the recently added auth
 </pre></div>
 
 
-<p>In <code>BundleServlet</code> we add the following code:</p>
+<p>In <tt>BundleServlet</tt> we add the following code:</p>
 <div class="codehilite"><pre><span class="kd">private</span> <span 
class="kd">volatile</span> <span class="kt">boolean</span> <span 
class="n">m_useAuth</span><span class="o">;</span>
 <span class="kd">private</span> <span class="kd">volatile</span> <span 
class="n">AuthenticationService</span> <span 
class="n">m_authService</span><span class="o">;</span>
 
@@ -302,12 +305,12 @@ In this article, the recently added auth
         <span class="o">.</span><span class="na">setService</span><span 
class="o">(</span><span class="n">AuthenticationService</span><span 
class="o">.</span><span class="na">class</span><span class="o">)</span>
         <span class="o">.</span><span class="na">setRequired</span><span 
class="o">(</span><span class="n">m_useAuth</span><span class="o">)</span>
         <span class="o">.</span><span class="na">setInstanceBound</span><span 
class="o">(</span><span class="kc">true</span><span class="o">)</span>
-        <span class="o">);</span>
+    <span class="o">);</span>
 <span class="o">}</span>
 </pre></div>
 
 
-<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>
+<p>As almost all of the services in ACE are managed by the Dependency Manager, 
we can leverage its dynamics to inject our <tt>BundleServlet</tt> with an 
instance of the <tt>AuthenticationService</tt> 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="nd">@Override</span>
@@ -322,21 +325,21 @@ In this article, the recently added auth
 <span class="o">}</span>
 
 <span class="kd">private</span> <span class="kt">boolean</span> <span 
class="nf">authenticate</span><span class="o">(</span><span 
class="n">HttpServletRequest</span> <span class="n">request</span><span 
class="o">)</span> <span class="o">{</span>
-    <span class="n">User</span> <span class="n">user</span> <span 
class="o">=</span> <span class="kc">null</span><span class="o">;</span>
     <span class="k">if</span> <span class="o">(</span><span 
class="n">m_useAuth</span><span class="o">)</span> <span class="o">{</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="na">authenticate</span><span 
class="o">(</span><span class="n">request</span><span class="o">);</span>
+        <span class="k">if</span> <span class="o">(</span><span 
class="n">user</span> <span class="o">==</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
+            <span class="n">m_log</span><span class="o">.</span><span 
class="na">log</span><span class="o">(</span><span 
class="n">LogService</span><span class="o">.</span><span 
class="na">LOG_INFO</span><span class="o">,</span> <span 
class="s">&quot;Authentication failure!&quot;</span><span class="o">);</span>
+        <span class="o">}</span>
+        <span class="k">return</span> <span class="o">(</span><span 
class="n">user</span> <span class="o">!=</span> <span 
class="kc">null</span><span class="o">);</span>
     <span class="o">}</span>
-    <span class="k">if</span> <span class="o">(</span><span 
class="n">user</span> <span class="o">==</span> <span 
class="kc">null</span><span class="o">)</span> <span class="o">{</span>
-        <span class="n">m_log</span><span class="o">.</span><span 
class="na">log</span><span class="o">(</span><span 
class="n">LogService</span><span class="o">.</span><span 
class="na">LOG_INFO</span><span class="o">,</span> <span 
class="s">&quot;Authentication failure!&quot;</span><span class="o">);</span>
-    <span class="o">}</span>
-    <span class="k">return</span> <span class="o">(</span><span 
class="n">user</span> <span class="o">!=</span> <span 
class="kc">null</span><span class="o">);</span>
+    <span class="k">return</span> <span class="kc">true</span><span 
class="o">;</span>
 <span class="o">}</span>
 </pre></div>
 
 
-<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 <code>AuthenticationProcessor</code>s.</p>
+<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 <tt>AuthenticationService</tt>, with the help 
of the registered <tt>AuthenticationProcessor</tt>s.</p>
 <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>
+<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 
<tt>ConnectionFactory</tt> service. This service can be configured using the 
PID <tt>org.apache.ace.connectionfactory</tt> (<em>note that it is a 
configuration factory!</em>), which would result in the following configuration 
for accessing our <tt>BundleServlet</tt>:</p>
 <div class="codehilite"><pre><span class="c"># What kind of authentication 
should we supply</span>
 <span class="na">authentication.type</span> <span class="o">=</span> <span 
class="s">basic</span>
 <span class="c"># The actual credentials for basic authentication</span>
@@ -347,7 +350,7 @@ In this article, the recently added auth
 </pre></div>
 
 
-<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>. </p>
+<p>When this configuration is supplied to the <tt>ConnectionFactory</tt>, it 
will provide a basic HTTP authentication header to each connection created for 
any URL starting with "<tt>http://localhost:8080/obr/</tt>"<sup id="fnref:6"><a 
href="#fn:6" rel="footnote">6</a></sup>. </p>
 <h3 id="configuring-the-management-agent">Configuring the management agent</h3>
 <p>…</p>
 <div class="footnote">
@@ -360,7 +363,7 @@ In this article, the recently added auth
 <p>Assuming that all components in the ACE 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>
 <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>
+<p>It is up to the implementation of <tt>AuthenticationService</tt> 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>
 <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 ACE 
server.&#160;<a href="#fnref:4" rev="footnote" title="Jump back to footnote 4 
in the text">&#8617;</a></p>
@@ -369,7 +372,7 @@ In this article, the recently added auth
 <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>
 <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>
+<p>Currently, a simple <tt>String#startsWith()</tt> 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>
 </li>
 </ol>
 </div></div>


Reply via email to