3 Authentication, Authorization and Accounting (AAA) Services - Developer guide
4 =============================================================================
9 Authentication, Authorization and Accounting (AAA) is a term for a
10 framework controlling access to resources, enforcing policies to use
11 those resources and auditing their usage. These processes are the
12 fundamental building blocks for effective network management and security.
14 Authentication provides a way of identifying a user, typically by
15 having the user enter a valid user name and valid password before access
16 is granted. The process of authentication is based on each user having a unique
17 set of criteria for gaining access. The AAA framework compares a user's
18 authentication credentials with other user credentials stored in a database.
19 If the credentials match, the user is granted access to the network.
20 If the credentials don't match, authentication fails and access is denied.
22 Authorization is the process of finding out what an authenticated user is
23 allowed to do within the system, which tasks can do, which API can call, etc.
24 The authorization process determines whether the user has the authority
25 to perform such actions.
27 Accounting is the process of logging the activity of an authenticated user,
28 for example, the amount of data a user has sent and/or received during a
29 session, which APIs called, etc.
35 Authentication, Authorization and Accounting.
38 A claim of access to a group of resources on the controller.
41 A group of resources, direct or indirect, physical, logical, or
42 virtual, for the purpose of access control.
45 A person who either owns or has access to a resource or group of
46 resources on the controller.
49 Opaque representation of a set of permissions, which is merely a
50 unique string as admin or guest.
53 Proof of identity such as user name and password, OTP, biometrics, or
57 A service or application that requires access to the controller.
60 A data set of validated assertions regarding a user, e.g. the role,
76 git clone https://git.opendaylight.org/gerrit/aaa
82 cd aaa && mvn clean install
88 AAA is automatically installed upon installation of odl-restconf, but you can
89 install it yourself directly from the Karaf console through the following
94 feature:install odl-aaa-shiro
99 The following are basic instructions to push your contributions to the project's
106 # make changes, add change id, etc.
108 git push ssh://{username}@git.opendaylight.org:29418/aaa.git HEAD:refs/for/master
110 AAA Framework implementations
111 -----------------------------
113 Since Boron release, the OpenDaylight's AAA services are based on the
114 `Apache Shiro <https://shiro.apache.org/>`_ Java Security Framework. The main
115 configuration file for AAA is located at “etc/shiro.ini” relative to the
116 OpenDaylight Karaf home directory.
121 The database (H2) used by ODL AAA Authentication store is not-cluster enabled.
122 When deployed in a clustered environment each node needs to have its AAA user
123 file synchronized using out of band means.
128 AAA is enabled through installing the odl-aaa-shiro feature. The vast majority
129 of OpenDaylight's northbound APIs (and all RESTCONF APIs) are protected by AAA
130 by default when installing the +odl-restconf+ feature, since the odl-aaa-shiro
131 is automatically installed as part of them.
136 Edit the “etc/opendaylight/datastore/initial/config/aaa-app-config.xml” file and replace the following:
148 Then, restart the Karaf process.
150 How application developers can leverage AAA to provide servlet security
151 -----------------------------------------------------------------------
153 Previously the servlet's web.xml was edited to add the AAAShiroFilter. This has been replaced with programmatic initialization.
155 The Neutron project uses this new style the Neutron `blueprint.xml <https://git.opendaylight.org/gerrit/gitweb?p=neutron.git;a=blob;f=northbound-api/src/main/resources/OSGI-INF/blueprint/blueprint.xml;h=a9dc57a97091d6c90da3e216a13523adbe698887;hb=refs/heads/master>`_ and Neutron `WebInitializer.java <https://git.opendaylight.org/gerrit/gitweb?p=neutron.git;a=blob;f=northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/WebInitializer.java;h=a615d02343505cef0d4cdd54b2f07f2a9fee9b75;hb=refs/heads/master>`_ are helpful references.
160 AAA plugin utilizes the Shiro Realms to support pluggable authentication &
161 authorization schemes. There are two parent types of realms:
163 - AuthenticatingRealm
165 - Provides no Authorization capability.
167 - Users authenticated through this type of realm are treated
172 - AuthorizingRealm is a more sophisticated AuthenticatingRealm,
173 which provides the additional mechanisms to distinguish users
176 - Useful for applications in which roles determine allowed
179 OpenDaylight contains five implementations:
183 - An AuthorizingRealm built to bridge the Shiro-based AAA service
184 with the h2-based AAA implementation.
186 - Exposes a RESTful web service to manipulate IdM policy on a
187 per-node basis. If identical AAA policy is desired across a
188 cluster, the backing data store must be synchronized using an out
191 - A python script located at “etc/idmtool” is included to help
192 manipulate data contained in the TokenAuthRealm.
194 - Enabled out of the box. This is the realm configured by default.
198 - An AuthorizingRealm built to extract identity information from IdM
199 data contained on an LDAP server.
201 - Extracts group information from LDAP, which is translated into
204 - Useful when federating against an existing LDAP server, in which
205 only certain types of users should have certain access privileges.
207 - Disabled out of the box.
209 - ODLJndiLdapRealmAuthNOnly
211 - The same as ODLJndiLdapRealm, except without role extraction.
212 Thus, all LDAP users have equal authentication and authorization
215 - Disabled out of the box.
217 - ODLActiveDirectoryRealm
219 - Wraps the generic ActiveDirectoryRealm provided by Shiro. This allows for
220 enhanced logging as well as isolation of all realms in a single package,
221 which enables easier import by consuming servlets.
223 - Disabled out of the box.
227 - This realm authenticates OpenDaylight users against the OpenStack's
228 Keystone server by using the
229 `Keystone's Identity API v3 <https://developer.openstack.org/api-ref/identity/v3/>`_
232 - Disabled out of the box.
236 More than one Realm implementation can be specified. Realms are attempted
237 in order until authentication succeeds or all realm sources are exhausted.
238 Edit the **securityManager.realms = $tokenAuthRealm** property in shiro.ini
239 and add all the realms needed separated by commas.
247 The TokenAuthRealm is the default Authorization Realm deployed in OpenDaylight.
248 TokenAuthRealm uses a direct authentication mechanism as shown in the following
251 .. figure:: ./images/aaa/direct-authentication.png
252 :alt: TokenAuthRealm direct authentication mechanism
254 TokenAuthRealm direct authentication mechanism
256 A user presents some credentials (e.g., username/password) directly to the
257 OpenDaylight controller token endpoint /oauth2/token and receives an access
258 token, which then can be used to access protected resources on the controller.
260 How to access the H2 database
261 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
263 The H2 database provides an optional front-end Web interface, which can be very
264 useful for new users. From the KARAF_HOME directory, you can run the following
265 command to enable the user interface:
269 java -cp ./data/cache/org.eclipse.osgi/bundles/217/1/.cp/h2-1.4.185.jar
270 org.h2.tools.Server -trace -pg -web -webAllowOthers -baseDir `pwd`
273 You can navigate to the following and login via the browser:
285 LDAP integration is provided in order to externalize identity management.
286 This configuration allows federation with an external LDAP server.
287 The user’s OpenDaylight role parameters are mapped to corresponding LDAP
288 attributes as specified by the groupRolesMap. Thus, an LDAP operator can
289 provision attributes for LDAP users that support different OpenDaylight role
292 ODLJndiLdapRealmAuthNOnly
293 ^^^^^^^^^^^^^^^^^^^^^^^^^
298 This is useful for setups where all LDAP users are allowed equal access.
306 This realm authenticates OpenDaylight users against the OpenStack's Keystone
307 server. This realm uses the
308 `Keystone's Identity API v3 <https://developer.openstack.org/api-ref/identity/v3/>`_
311 .. figure:: ./images/aaa/keystonerealm-authentication.png
312 :alt: KeystoneAuthRealm authentication mechanism
314 KeystoneAuthRealm authentication/authorization mechanism
316 As can shown on the above diagram, once configured, all the RESTCONF APIs calls
317 will require sending **user**, **password** and optionally **domain** (1). Those
318 credentials are used to authenticate the call against the Keystone server (2) and,
319 if the authentication succeeds, the call will proceed to the MDSAL (3). The
320 credentials must be provisioned in advance within the Keystone Server. The user
321 and password are mandatory, while the domain is optional, in case it is not
322 provided within the REST call, the realm will default to (**Default**),
323 which is hard-coded. The default domain can be also configured through the
324 *shiro.ini* file (see the :doc:`AAA User Guide <user-guide>`).
326 The protocol between the Controller and the Keystone Server (2) can be either
327 HTTPS or HTTP. In order to use HTTPS the Keystone Server's certificate
328 must be exported and imported on the Controller (see the :ref:`Certificate Management <aaa-certificate-management>` section).
330 Authorization Configuration
331 ---------------------------
333 OpenDaylight supports two authorization engines at present, both of which are
334 roughly similar in behavior:
336 - Shiro-Based Authorization
338 - MDSAL-Based Dynamic Authorization
342 The preferred mechanism for configuring AAA Authentication is the
343 MDSAL-Based Dynamic Authorization. Read the following section.
345 Shiro-Based Static Authorization
346 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
348 OpenDaylight AAA has support for Role Based Access Control (RBAC) based
349 on the Apache Shiro permissions system. Configuration of the authorization
350 system is done off-line; authorization currently cannot be configured
351 after the controller is started. The Authorization provided by this mechanism
352 is aimed towards supporting coarse-grained security policies, the MDSAL-Based
353 mechanism allows for a more robust configuration capabilities. `Shiro-based
354 Authorization <http://shiro.apache.org/web.html#Web-%7B%7B%5Curls%5C%7D%7D>`_
355 describes how to configure the Authentication feature in detail.
359 The Shiro-Based Authorization that uses the *shiro.ini* URLs section to
360 define roles requirements is **deprecated** and **discouraged** since the
361 changes made to the file are only honored on a controller restart.
363 Shiro-Based Authorization is not **cluster-aware**, so the changes made on
364 the *shiro.ini* file have to be replicated on every controller instance
365 belonging to the cluster.
367 The URL patterns are matched relative to the Servlet context leaving room
368 for ambiguity, since many endpoints may match (i.e., "/restconf/modules" and
369 "/auth/modules" would both match a "/modules/\**" rule).
371 MDSAL-Based Dynamic Authorization
372 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
373 The MDSAL-Based Dynamic authorization uses the MDSALDynamicAuthorizationFilter
374 engine to restrict access to particular URL endpoint patterns. Users may define
375 a list of policies that are insertion-ordered. Order matters for that list of
376 policies, since the first matching policy is applied. This choice was made to
377 emulate behavior of the Shiro-Based Authorization mechanism.
379 A **policy** is a key/value pair, where the key is a **resource**
380 (i.e., a "URL pattern") and the value is a list of **permissions** for the
381 resource. The following describes the various elements of a policy:
383 - **Resource**: the resource is a string URL pattern as outlined by
384 Apache Shiro. For more information, see http://shiro.apache.org/web.html.
386 - **Description**: an optional description of the URL endpoint and why it is
389 - **Permissions list**: a list of permissions for a particular policy. If more
390 than one permission exists in the permissions list they are evaluated using
391 logical "OR". A permission describes the prerequisites to perform HTTP
392 operations on a particular endpoint. The following describes the various
393 elements of a permission:
395 + **Role**: the role required to access the target URL endpoint.
396 + **Actions list**: a leaf-list of HTTP permissions that are allowed for a
397 Subject possessing the required role.
399 This an example on how to limit access to the modules endpoint:
404 put URL: /restconf/config/aaa:http-authorization/policies
406 headers: Content-Type: application/json Accept: application/json
411 [ { "aaa:resource": "/restconf/modules/**",
412 "aaa:permissions": [ { "aaa:role": "admin",
413 "aaa:actions": [ "get",
426 The above example locks down access to the modules endpoint (and any URLS
427 available past modules) to the "admin" role. Thus, an attempt from the OOB
428 *admin* user will succeed with 2XX HTTP status code, while an attempt from the
429 OOB *user* user will fail with HTTP status code 401, as the user *user* is not
430 granted the "admin" role.
432 Accounting Configuration
433 ------------------------
435 Accounting is handled through the standard slf4j logging mechanisms used by the
436 rest of OpenDaylight. Thus, one can control logging verbosity through
437 manipulating the log levels for individual packages and classes directly through
438 the Karaf console, JMX, or etc/org.ops4j.pax.logging.cfg. In normal operations,
439 the default levels exposed do not provide much information about AAA services;
440 this is due to the fact that logging can severely degrade performance.
442 All AAA logging is output to the standard karaf.log file. For debugging purposes
443 (i.e., to enable maximum verbosity), issue the following command:
447 log:set TRACE org.opendaylight.aaa
449 Enable Successful/Unsuccessful Authentication Attempts Logging
450 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
452 By default, successful/unsuccessful authentication attempts are NOT logged. This
453 is due to the fact that logging can severely decrease REST performance.
455 It is possible to add custom AuthenticationListener(s) to the Shiro-based
456 configuration, allowing different ways to listen for successful/unsuccessful
457 authentication attempts. Custom AuthenticationListener(s) must implement
458 the org.apache.shiro.authc.AuthenticationListener interface.
460 .. _aaa-certificate-management:
462 Certificate Management
463 ----------------------
465 The **Certificate Management Service** is used to manage the keystores and
466 certificates at the OpenDaylight distribution to easily provides the TLS
469 The Certificate Management Service managing two keystores:
471 1. **OpenDaylight Keystore** which holds the OpenDaylight distribution
472 certificate self sign certificate or signed certificate from a root CA based
473 on generated certificate request.
475 2. **Trust Keystore** which holds all the network nodes certificates that shall
476 to communicate with the OpenDaylight distribution through TLS communication.
478 The Certificate Management Service stores the keystores (OpenDaylight & Trust)
479 as *.jks* files under configuration/ssl/ directory. Also the keystores
480 could be stored at the MD-SAL datastore in case OpenDaylight distribution
481 running at cluster environment. When the keystores are stored at MD-SAL,
482 the Certificate Management Service rely on the **Encryption-Service** to encrypt
483 the keystore data before storing it to MD-SAL and decrypted at runtime.
485 How to use the Certificate Management Service to manage the TLS communication
486 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
488 The following are the steps to configure the TLS communication within your
491 1. It is assumed that there exists an already created OpenDaylight distribution
492 project following `this guide
493 <https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Startup_Project_Archetype#Part_1_-_Build_with_a_simple_.27Example.27_module>`_.
495 2. In the implementation bundle the following artifact must be added to its
496 *pom.xml* file as dependency.
501 <groupId>org.opendaylight.aaa</groupId>
502 <artifactId>aaa-cert</artifactId>
503 <version>0.5.0-SNAPSHOT</version>
506 3. Using the provider class in the implementation bundle needs to define a
507 variable holding the Certificate Manager Service as in the following example:
511 import org.opendaylight.aaa.cert.api.ICertificateManager;
512 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
514 public class UseCertManagerExampleProvider {
515 private final DataBroker dataBroker;
516 private final ICertificateManager caManager;
518 public EncSrvExampleProvider(final DataBroker dataBroker, final ICertificateManager caManager) {
519 this.dataBroker = dataBroker;
520 this.caManager = caManager;
522 public SSLEngine createSSLEngine() {
523 final SSLContext sslContext = caManager.getServerContext();
524 if (sslContext != null) {
525 final SSLEngine sslEngine = sslContext.createSSLEngine();
526 sslEngine.setEnabledCipherSuites(caManager.getCipherSuites());
527 // DO the Implementation
534 public void close() {
539 4. The Certificate Manager Service provides two main methods that are needed to
540 establish the *SSLEngine* object, *getServerContext()* and *getCipherSuites()*
541 as the above example shows. It also provides other methods such as
542 *getODLKeyStore()* and *getTrustKeyStore()* that gives access to the
543 OpenDaylight and Trust keystores.
545 5. Now the *ICertificateManager* need to be passed as an argument to the
546 *UseCertManagerExampleProvider* within the implementation bundle blueprint
547 configuration. The following example shows how:
551 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
552 xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
553 odl:use-default-for-reference-types="true">
554 <reference id="dataBroker"
555 interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
556 odl:type="default" />
557 <reference id="aaaCertificateManager"
558 interface="org.opendaylight.aaa.cert.api.ICertificateManager"
559 odl:type="default-certificate-manager" />
561 class="org.opendaylight.UseCertManagerExample.impl.UseCertManagerExampleProvider"
562 init-method="init" destroy-method="close">
563 <argument ref="dataBroker" />
564 <argument ref="aaaCertificateManager" />
568 6. After finishing the bundle implementation the feature module needs to be
569 updated to include the *aaa-cert* feature in its feature bundle pom.xml file.
574 <aaa.version>0.5.0-SNAPSHOT</aaa.version>
577 <groupId>org.opendaylight.aaa</groupId>
578 <artifactId>features-aaa</artifactId>
579 <version>${aaa.version}</version>
580 <classifier>features</classifier>
584 7. Now, in the feature.xml file add the Certificate Manager Service feature and
589 <repository>mvn:org.opendaylight.aaa/features-aaa/{VERSION}/xml/features</repository>
591 The Certificate Manager Service feature can be included inside the
592 implementation bundle feature as shown in the following example:
596 <feature name='odl-UseCertManagerExample' version='${project.version}'
597 description='OpenDaylight :: UseCertManagerExample'>
598 <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
599 <feature version='${aaa.version}'>odl-aaa-cert</feature>
600 <bundle>mvn:org.opendaylight.UseCertManagerExample/UseCertManagerExample-impl/{VERSION}</bundle>
603 8. Now the project can be built and the OpenDaylight distribution started to
604 continue with the configuration process. See the User Guide for more details.
609 The **AAA Encryption Service** is used to encrypt the OpenDaylight users'
610 passwords and TLS communication certificates. This section shows how to use the
611 AAA Encryption Service with an OpenDaylight distribution project to encrypt data.
613 1. It is assumed that there exists an already created OpenDaylight distribution
614 project following `this guide
615 <https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Startup_Project_Archetype#Part_1_-_Build_with_a_simple_.27Example.27_module>`_.
617 2. In the implementation bundle the following artifact must be added to its
618 *pom.xml* file as dependency.
623 <groupId>org.opendaylight.aaa</groupId>
624 <artifactId>aaa-encrypt-service</artifactId>
625 <version>0.5.0-SNAPSHOT</version>
628 3. Using the provider class in the implementation bundle needs to define a
629 variable holding the Encryption Service as in the following example:
633 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
634 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
636 public class EncSrvExampleProvider {
637 private final DataBroker dataBroker;
638 private final AAAEncryptionService encryService;
640 public EncSrvExampleProvider(final DataBroker dataBroker, final AAAEncryptionService encryService) {
641 this.dataBroker = dataBroker;
642 this.encryService = encryService;
647 public void close() {
652 The AAAEncryptionService can be used to encrypt and decrypt any data based on
655 4. Now the *AAAEncryptionService* needs to be passed as an argument to the
656 *EncSrvExampleProvider* within the implementation bundle blueprint
657 configuration. The following example shows how:
661 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
662 xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
663 odl:use-default-for-reference-types="true">
664 <reference id="dataBroker"
665 interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
666 odl:type="default" />
667 <reference id="encryService" interface="org.opendaylight.aaa.encrypt.AAAEncryptionService"/>
669 class="org.opendaylight.EncSrvExample.impl.EncSrvExampleProvider"
670 init-method="init" destroy-method="close">
671 <argument ref="dataBroker" />
672 <argument ref="encryService" />
676 5. After finishing the bundle implementation the feature module needs to be
677 updated to include the *aaa-encryption-service* feature in its feature bundle
683 <groupId>org.opendaylight.aaa</groupId>
684 <artifactId>features-aaa</artifactId>
685 <version>${aaa.version}</version>
686 <classifier>features</classifier>
690 It is also necessary to add the *aaa.version* in the properties section:
695 <aaa.version>0.5.0-SNAPSHOT</aaa.version>
698 6. Now, in the feature.xml file add the Encryption Service feature and its
703 <repository>mvn:org.opendaylight.aaa/features-aaa/{VERSION}/xml/features</repository>
705 The Encryption Service feature can be included inside the implementation bundle
706 feature as shown in the following example:
710 <feature name='odl-EncSrvExample' version='${project.version}' description='OpenDaylight :: EncSrvExample'>
711 <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
712 <feature version='${aaa.version}'>odl-aaa-encryption-service</feature>
713 <feature version='${project.version}'>odl-EncSrvExample-api</feature>
714 <bundle>mvn:org.opendaylight.EncSrvExample/EncSrvExample-impl/{VERSION}</bundle>
717 7. Now the project can be built and the OpenDaylight distribution started to
718 continue with the configuration process. See the User Guide for more details.