Title: ACE authentication guide
[TOC]
## Introduction
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 *authentication*, which gives you the ability to
verify the identity of someone. Once the identity is known, one can apply *authorization*
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 how to configure
authentication to your situation.
More details on the design of the authentication mechanism in ACE can be found in the
[design documentation](/docs/design/authentication-design.html).
## Configuring authentication
By default, ACE has no form of authentication enabled. While this is sufficient for
demonstration purposes, you might want to change this prior to putting ACE into
production. There are three parts that need to be configured:
1. the "remote services" exposed by the ACE server need to enable authentication;
2. the internal client(s) (which covers the ACE server itself!) need to know what
authentication mechanism should be used. For convenience, the client(s) can make use of
the ConnectionFactory to create authenticated connections to the ACE server;
3. the management agent, which also needs to know what credentials it can use to access
the ACE server.
One of the easiest forms of authentication to use in ACE is HTTP BASIC authentication,
which means that username/password credentials are sent with each request to the server.
Note that this is done in clear text, so you might want to add an additional layer of
security by using TLS/SSL encryption as well.
### Remote services
There are several endpoints exposed by the ACE server as listed in the following table,
along with the endpoint(s) they expose:
Name | Description | Endpoint | Configuration PID[^1]
------- | --------------- | ------------ | ---------------------
BundleServlet | provides access to the OBR (bundle repository) of ACE | /obr | o.a.a.obr.servlet
DeploymentServlet | handles the actual provisioning of deployment packages to a target | /deployment |o.a.a.deployment.servlet
LogServlet | allows any number of logs for a target to be synchronized and accessed | /auditlog[^2] | o.a.a.server.log.servlet.factory
**note: this is a configuration factory!**
RepositoryServlet | provides access to the various (artifact/feature/distribution/target) internal repositories of ACE | /repository | o.a.a.repository.servlet.
RepositoryServlet
RepositoryReplicationServlet | allows *relay nodes* to replicate the internal repositories of ACE | /replication | o.a.a.repository.servlet.
RepositoryReplicationServlet
RESTClientServlet | provides the RESTful interface to ACE |/client | o.a.a.client.rest
VaadinServlet | provides the Vaadin web interface | /ace | o.a.a.webui.vaadin
| | |
To configure authentication, for example, for the OBR servlet, you need to edit
conf/org.apache.ace.obr.servlet.cfg to edit/include the following:
:::properties
# Endpoint for this servlet
org.apache.ace.server.servlet.endpoint = /obr
# Whether or not authentication is to be used
authentication.enabled = true
Note that the authentication.enabled property allows us to enable or disable the
authentication check for this servlet.
This is the *only* thing that is needed to enable authentication for remote services.
What authentication mechanism is to be used is up to the caller/client: it should provide
the right credentials in order to pass the authentication check, see also the [design
documentation](/docs/design/authentication-design.html).
### The connection factory
Now that the remote services no longer accepting unauthenticated requests, we need to
configure the client(s) in order to make use of authentication as well. Note that due to
the modular architecture of the ACE server, the server itself is also regarded a client
meaning that it needs to be configured to use authentication as well! For convenience, the
client(s) can use the ConnectionFactory supplied by ACE for creating a connection
with the proper authentication credentials already configured. This also simplies the
configuration at the client side significantly, as we only need to configure a single
service.
The ConnectionFactory service can be configured using the PID
org.apache.ace.connectionfactory (**note** that it is a configuration factory,
accepting multiple configurations!). To configure the authentication credentials for the
OBR servlet, you need to edit or create a file named obr.cfg and place it in the
org.apache.ace.connectionfactory directory. For HTTP BASIC authentication, the
following key/values need to be present:
:::properties
# What kind of authentication should we supply
authentication.type = basic
# The actual credentials for basic authentication
authentication.user.name = d
authentication.user.password = f
# What is the base URL that these credentials apply to:
authentication.baseURL = http://localhost:8080/obr/
When this configuration is supplied to the ConnectionFactory, it will provide a
basic HTTP authentication header to each connection created for any URL starting with
"http://localhost:8080/obr/"[^3]. To disable authentication for a particular URL,
the authentication.type option can be set to none.
### The management agent
The management agent itself also needs to use authentication to communicate with the
remote services of the ACE server. Although it would be possible to reuse the same
ConnectionFactory implementation as the server, the current implementation uses a
different approach to minimize the number of dependencies. To configure authentication for
the management agent, you need to supply one or more system properties[^4]:
:::sh
[localhost:~/]$ java -Dagent.connection.authtype=BASIC \
-Dagent.connection.username=d -Dagent.connection.password=f \
-Dagent.identification.agentid=target-1 \
target.jar
### Configuring users
In order to successfully authenticate a user, it needs a corresponding User that
can be obtained from the UserAdmin service. Initially, ACE imports a small set of
users and roles defined in the
"org.apache.ace.server.repository.factory/ace-user.cfg" configuration file. One
could update this file in order to add users[^5], or add them, for example, [by
hand](/docs/user-management-guide.html). Alternatively, you can also use another backend
for the used UserAdmin service, that connects to a LDAP server.
## Troubleshooting
If after configuring the authentication of ACE things no longer work, it can be hard to
find the exact cause of this. In this section, some pointers are given to help you to find
the probably cause of the problem.
I've enabled authentication, but I can still use all services without passing any credentials!
: If you've updated the configuration files of a running server or management agent, the
configuration files are not automatically picked up by default. You need to stop the
server/management agent, clean its felix-cache folder and start it again.
With authentication enabled, how can I test whether the endpoints accept my credentials?
: In order to test the remote endpoints of ACE, you can use a tool like [REST
client](http://code.google.com/p/rest-client/). It allows you to enter credentials for any
given URL.
After enabling authentication, I do not get any errors after starting the ACE server, but it doesn't function correctly!
: Is the connection factory properly configured? Are *all* authentication.type
options correctly set to basic and are the username/passwords correctly set? Are
the configured base URLs not overlapping each other (e.g.: baseURL =
http://localhost:8080/ and baseURL = http://localhost:8080/obr)?
After enabling authentication, the management agent(s) no longer functions/I do not see them added in the web UI.
: Did you pass the auth=/path/to/config/file(s) option to the management agent to
configure the connection factory? Are those files correctly stating the
"authentication.type = basic", including the username and password for the
desired URLs? Can you access the URLs mentioned in the configuration files with a tool
like [REST client](http://code.google.com/p/rest-client/)?
I do not want basic HTTP authentication, I want to use (fill in the kind of authentication)!
: Instead, you can also use [two-way SSL using client
certificates](/docs/using-client-certificates.html), but you can add your own
authentication processor as well. See the [design
documentation](/docs/design/authentication-design.html) for more details.
[^1]: The common prefix of the shown configuration PIDs are abbreviated, so
"o.a.a" stands for "org.apache.ace".
[^2]: 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.
[^3]: Currently, a simple String#startsWith() 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.
[^4]: You probably do not want to specify the credentials using the commandline, see also
[ACE-496](https://issues.apache.org/jira/browse/ACE-496).
[^5]: Make sure to clean the bundle-cache directory before restarting the server,
otherwise the new configuration files will not be picked up!