Merge "Add SXP Fluorine release notes" into stable/fluorine
[docs.git] / docs / developer-guide / authentication-and-authorization-services.rst
1 .. _aaa-dev-guide:
2
3 Authentication, Authorization and Accounting (AAA) Services
4 ===========================================================
5
6 Overview
7 --------
8
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.
13
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.
21
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.
26
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.
30
31 Terms And Definitions
32 ^^^^^^^^^^^^^^^^^^^^^
33
34 AAA
35     Authentication, Authorization and Accounting.
36
37 Token
38     A claim of access to a group of resources on the controller.
39
40 Domain
41     A group of resources, direct or indirect, physical, logical, or
42     virtual, for the purpose of access control.
43
44 User
45     A person who either owns or has access to a resource or group of
46     resources on the controller.
47
48 Role
49     Opaque representation of a set of permissions, which is merely a
50     unique string as admin or guest.
51
52 Credential
53     Proof of identity such as user name and password, OTP, biometrics, or
54     others.
55
56 Client
57     A service or application that requires access to the controller.
58
59 Claim
60     A data set of validated assertions regarding a user, e.g. the role,
61     domain, name, etc.
62
63 IdP
64     Identity Provider.
65
66
67 Quick Start
68 -----------
69
70 Building
71 ^^^^^^^^
72 Get the code:
73
74 .. code-block:: bash
75
76     git clone https://git.opendaylight.org/gerrit/aaa
77
78 Build it:
79
80 .. code-block:: bash
81
82     cd aaa && mvn clean install
83
84
85 Installing
86 ^^^^^^^^^^
87
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
90 command:
91
92 ::
93
94     feature:install odl-aaa-shiro
95
96 Pushing changes
97 ^^^^^^^^^^^^^^^
98
99 The following are basic instructions to push your contributions to the project's
100 GIT repository:
101
102 .. code-block:: bash
103
104     git add .
105     git commit -s
106     # make changes, add change id, etc.
107     git commit --amend
108     git push ssh://{username}@git.opendaylight.org:29418/aaa.git HEAD:refs/for/master
109
110 AAA Framework implementations
111 -----------------------------
112
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.
117
118 Known limitations
119 ^^^^^^^^^^^^^^^^^
120
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.
124
125 How to enable AAA
126 -----------------
127
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.
132
133 How to disable AAA
134 ------------------
135
136 Edit the “etc/shiro.ini” file and replace the following:
137
138 ::
139
140     /** = authcBasic
141
142 with
143
144 ::
145
146     /** = anon
147
148 Then, restart the Karaf process.
149
150 How application developers can leverage AAA to provide servlet security
151 -----------------------------------------------------------------------
152
153 In order to provide security to a servlet, add the following to the
154 servlet’s web.xml file as the first filter definition:
155
156 .. code-block:: xml
157
158     <context-param>
159       <param-name>shiroEnvironmentClass</param-name>
160       <param-value>org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment</param-value>
161     </context-param>
162
163     <listener>
164         <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
165     </listener>
166
167     <filter>
168         <filter-name>ShiroFilter</filter-name>
169         <filter-class>org.opendaylight.aaa.shiro.filters.AAAShiroFilter</filter-class>
170     </filter>
171
172     <filter-mapping>
173         <filter-name>AAAShiroFilter</filter-name>
174         <url-pattern>/*</url-pattern>
175     </filter-mapping>
176
177 .. note::
178
179     It is very important to place this AAAShiroFilter as the first
180     javax.servlet.Filter, as Jersey applies Filters in the order they
181     appear within web.xml. Placing the AAAShiroFilter first ensures
182     incoming HTTP/HTTPS requests have proper credentials before any
183     other filtering is attempted.
184
185 AAA Realms
186 ----------
187
188 AAA plugin utilizes the Shiro Realms to support pluggable authentication &
189 authorization schemes. There are two parent types of realms:
190
191 -  AuthenticatingRealm
192
193    -  Provides no Authorization capability.
194
195    -  Users authenticated through this type of realm are treated
196       equally.
197
198 -  AuthorizingRealm
199
200    -  AuthorizingRealm is a more sophisticated AuthenticatingRealm,
201       which provides the additional mechanisms to distinguish users
202       based on roles.
203
204    -  Useful for applications in which roles determine allowed
205       capabilities.
206
207 OpenDaylight contains five implementations:
208
209 -  TokenAuthRealm
210
211    -  An AuthorizingRealm built to bridge the Shiro-based AAA service
212       with the h2-based AAA implementation.
213
214    -  Exposes a RESTful web service to manipulate IdM policy on a
215       per-node basis. If identical AAA policy is desired across a
216       cluster, the backing data store must be synchronized using an out
217       of band method.
218
219    -  A python script located at “etc/idmtool” is included to help
220       manipulate data contained in the TokenAuthRealm.
221
222    -  Enabled out of the box. This is the realm configured by default.
223
224 -  ODLJndiLdapRealm
225
226    -  An AuthorizingRealm built to extract identity information from IdM
227       data contained on an LDAP server.
228
229    -  Extracts group information from LDAP, which is translated into
230       OpenDaylight roles.
231
232    -  Useful when federating against an existing LDAP server, in which
233       only certain types of users should have certain access privileges.
234
235    -  Disabled out of the box.
236
237 -  ODLJndiLdapRealmAuthNOnly
238
239    -  The same as ODLJndiLdapRealm, except without role extraction.
240       Thus, all LDAP users have equal authentication and authorization
241       rights.
242
243    -  Disabled out of the box.
244
245 -  ODLActiveDirectoryRealm
246
247    -  Wraps the generic ActiveDirectoryRealm provided by Shiro. This allows for
248       enhanced logging as well as isolation of all realms in a single package,
249       which enables easier import by consuming servlets.
250
251    -  Disabled out of the box.
252
253 -  KeystoneAuthRealm
254
255    -  This realm authenticates OpenDaylight users against the OpenStack's
256       Keystone server by using the
257       `Keystone's Identity API v3 <https://developer.openstack.org/api-ref/identity/v3/>`_
258       or later.
259
260    - Disabled out of the box.
261
262 .. note::
263
264     More than one Realm implementation can be specified. Realms are attempted
265     in order until authentication succeeds or all realm sources are exhausted.
266     Edit the **securityManager.realms = $tokenAuthRealm** property in shiro.ini
267     and add all the realms needed separated by commas.
268
269 TokenAuthRealm
270 ^^^^^^^^^^^^^^
271
272 How it works
273 ~~~~~~~~~~~~
274
275 The TokenAuthRealm is the default Authorization Realm deployed in OpenDaylight.
276 TokenAuthRealm uses a direct authentication mechanism as shown in the following
277 picture:
278
279 .. figure:: ./images/aaa/direct-authentication.png
280    :alt: TokenAuthRealm direct authentication mechanism
281
282    TokenAuthRealm direct authentication mechanism
283
284 A user presents some credentials (e.g., username/password) directly to the
285 OpenDaylight controller token endpoint /oauth2/token and receives an access
286 token, which then can be used to access protected resources on the controller.
287
288 How to access the H2 database
289 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
290
291 The H2 database provides an optional front-end Web interface, which can be very
292 useful for new users. From the KARAF_HOME directory, you can run the following
293 command to enable the user interface:
294
295 .. code-block:: bash
296
297     java -cp ./data/cache/org.eclipse.osgi/bundles/217/1/.cp/h2-1.4.185.jar
298         org.h2.tools.Server -trace -pg -web -webAllowOthers -baseDir `pwd`
299
300
301 You can navigate to the following and login via the browser:
302
303 ::
304
305     http://{IP}:8082/
306
307 ODLJndiLdapRealm
308 ^^^^^^^^^^^^^^^^
309
310 How it works
311 ~~~~~~~~~~~~
312
313 LDAP integration is provided in order to externalize identity management.
314 This configuration allows federation with an external LDAP server.
315 The user’s OpenDaylight role parameters are mapped to corresponding LDAP
316 attributes as specified by the groupRolesMap. Thus, an LDAP operator can
317 provision attributes for LDAP users that support different OpenDaylight role
318 structures.
319
320 ODLJndiLdapRealmAuthNOnly
321 ^^^^^^^^^^^^^^^^^^^^^^^^^
322
323 How it works
324 ~~~~~~~~~~~~
325
326 This is useful for setups where all LDAP users are allowed equal access.
327
328 KeystoneAuthRealm
329 ^^^^^^^^^^^^^^^^^
330
331 How it works
332 ~~~~~~~~~~~~
333
334 This realm authenticates OpenDaylight users against the OpenStack's Keystone
335 server. This realm uses the
336 `Keystone's Identity API v3 <https://developer.openstack.org/api-ref/identity/v3/>`_
337 or later.
338
339 .. figure:: ./images/aaa/keystonerealm-authentication.png
340    :alt: KeystoneAuthRealm authentication mechanism
341
342    KeystoneAuthRealm authentication/authorization mechanism
343
344 As can shown on the above diagram, once configured, all the RESTCONF APIs calls
345 will require sending **user**, **password** and optionally **domain** (1). Those
346 credentials are used to authenticate the call against the Keystone server (2) and,
347 if the authentication succeeds, the call will proceed to the MDSAL (3). The
348 credentials must be provisioned in advance within the Keystone Server. The user
349 and password are mandatory, while the domain is optional, in case it is not
350 provided within the REST call, the realm will default to (**Default**),
351 which is hard-coded. The default domain can be also configured through the
352 *shiro.ini* file (see the :doc:`AAA User Guide <../user-guide/authentication-and-authorization-services>`).
353
354 The protocol between the Controller and the Keystone Server (2) can be either
355 HTTPS or HTTP. In order to use HTTPS the Keystone Server's certificate
356 must be exported and imported on the Controller (see the :ref:`Certificate Management <aaa-certificate-management>` section).
357
358 Authorization Configuration
359 ---------------------------
360
361 OpenDaylight supports two authorization engines at present, both of which are
362 roughly similar in behavior:
363
364 - Shiro-Based Authorization
365
366 - MDSAL-Based Dynamic Authorization
367
368 .. note::
369
370     The preferred mechanism for configuring AAA Authentication is the
371     MDSAL-Based Dynamic Authorization. Read the following section.
372
373 Shiro-Based Static Authorization
374 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
375
376 OpenDaylight AAA has support for Role Based Access Control (RBAC) based
377 on the Apache Shiro permissions system. Configuration of the authorization
378 system is done off-line; authorization currently cannot be configured
379 after the controller is started. The Authorization provided by this mechanism
380 is aimed towards supporting coarse-grained security policies, the MDSAL-Based
381 mechanism allows for a more robust configuration capabilities. `Shiro-based
382 Authorization <http://shiro.apache.org/web.html#Web-%7B%7B%5Curls%5C%7D%7D>`_
383 describes how to configure the Authentication feature in detail.
384
385 .. note::
386
387     The Shiro-Based Authorization that uses the *shiro.ini* URLs section to
388     define roles requirements is **deprecated** and **discouraged** since the
389     changes made to the file are only honored on a controller restart.
390
391     Shiro-Based Authorization is not **cluster-aware**, so the changes made on
392     the *shiro.ini* file have to be replicated on every controller instance
393     belonging to the cluster.
394
395     The URL patterns are matched relative to the Servlet context leaving room
396     for ambiguity, since many endpoints may match (i.e., "/restconf/modules" and
397     "/auth/modules" would both match a "/modules/\**" rule).
398
399 MDSAL-Based Dynamic Authorization
400 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
401 The MDSAL-Based Dynamic authorization uses the MDSALDynamicAuthorizationFilter
402 engine to restrict access to particular URL endpoint patterns. Users may define
403 a list of policies that are insertion-ordered. Order matters for that list of
404 policies, since the first matching policy is applied. This choice was made to
405 emulate behavior of the Shiro-Based Authorization mechanism.
406
407 A **policy** is a key/value pair, where the key is a **resource**
408 (i.e., a "URL pattern") and the value is a list of **permissions** for the
409 resource. The following describes the various elements of a policy:
410
411 - **Resource**: the resource is a string URL pattern as outlined by
412   Apache Shiro. For more information, see http://shiro.apache.org/web.html.
413
414 - **Description**: an optional description of the URL endpoint and why it is
415   being secured.
416
417 - **Permissions list**: a list of permissions for a particular policy. If more
418   than one permission exists in the permissions list they are evaluated using
419   logical "OR". A permission describes the prerequisites to perform HTTP
420   operations on a particular endpoint. The following describes the various
421   elements of a permission:
422
423   + **Role**: the role required to access the target URL endpoint.
424   + **Actions list**: a leaf-list of HTTP permissions that are allowed for a
425     Subject possessing the required role.
426
427 This an example on how to limit access to the modules endpoint:
428
429 ::
430
431     HTTP Operation:
432     put URL: /restconf/config/aaa:http-authorization/policies
433
434     headers: Content-Type: application/json Accept: application/json
435
436     body:
437       { "aaa:policies":
438         { "aaa:policies":
439           [ { "aaa:resource": "/restconf/modules/**",
440             "aaa:permissions": [ { "aaa:role": "admin",
441                                    "aaa:actions": [ "get",
442                                                     "post",
443                                                     "put",
444                                                     "patch",
445                                                     "delete"
446                                                   ]
447                                  }
448                                ]
449             }
450           ]
451         }
452       }
453
454 The above example locks down access to the modules endpoint (and any URLS
455 available past modules) to the "admin" role. Thus, an attempt from the OOB
456 *admin* user will succeed with 2XX HTTP status code, while an attempt from the
457 OOB *user* user will fail with HTTP status code 401, as the user *user* is not
458 granted the "admin" role.
459
460 Accounting Configuration
461 ------------------------
462
463 Accounting is handled through the standard slf4j logging mechanisms used by the
464 rest of OpenDaylight. Thus, one can control logging verbosity through
465 manipulating the log levels for individual packages and classes directly through
466 the Karaf console, JMX, or etc/org.ops4j.pax.logging.cfg. In normal operations,
467 the default levels exposed do not provide much information about AAA services;
468 this is due to the fact that logging can severely degrade performance.
469
470 All AAA logging is output to the standard karaf.log file. For debugging purposes
471 (i.e., to enable maximum verbosity), issue the following command:
472
473 ::
474
475     log:set TRACE org.opendaylight.aaa
476
477 Enable Successful/Unsuccessful Authentication Attempts Logging
478 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
479
480 By default, successful/unsuccessful authentication attempts are NOT logged. This
481 is due to the fact that logging can severely decrease REST performance.
482
483 It is possible to add custom AuthenticationListener(s) to the Shiro-based
484 configuration, allowing different ways to listen for successful/unsuccessful
485 authentication attempts. Custom AuthenticationListener(s) must implement
486 the org.apache.shiro.authc.AuthenticationListener interface.
487
488 .. _aaa-certificate-management:
489
490 Certificate Management
491 ----------------------
492
493 The **Certificate Management Service** is used to manage the keystores and
494 certificates at the OpenDaylight distribution to easily provides the TLS
495 communication.
496
497 The Certificate Management Service managing two keystores:
498
499 1. **OpenDaylight Keystore** which holds the OpenDaylight distribution
500    certificate self sign certificate or signed certificate from a root CA based
501    on generated certificate request.
502
503 2. **Trust Keystore** which holds all the network nodes certificates that shall
504    to communicate with the OpenDaylight distribution through TLS communication.
505
506 The Certificate Management Service stores the keystores (OpenDaylight & Trust)
507 as *.jks* files under configuration/ssl/ directory. Also the keystores
508 could be stored at the MD-SAL datastore in case OpenDaylight distribution
509 running at cluster environment. When the keystores are stored at MD-SAL,
510 the Certificate Management Service rely on the **Encryption-Service** to encrypt
511 the keystore data before storing it to MD-SAL and decrypted at runtime.
512
513 How to use the Certificate Management Service to manage the TLS communication
514 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
515
516 The following are the steps to configure the TLS communication within your
517 feature or module:
518
519 1. It is assumed that there exists an already created OpenDaylight distribution
520    project following `this guide
521    <https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Startup_Project_Archetype#Part_1_-_Build_with_a_simple_.27Example.27_module>`_.
522
523 2. In the implementation bundle the following artifact must be added to its
524    *pom.xml* file as dependency.
525
526 .. code-block:: xml
527
528     <dependency>
529       <groupId>org.opendaylight.aaa</groupId>
530       <artifactId>aaa-cert</artifactId>
531       <version>0.5.0-SNAPSHOT</version>
532     </dependency>
533
534 3. Using the provider class in the implementation bundle needs to define a
535    variable holding the Certificate Manager Service as in the following example:
536
537 .. code-block:: java
538
539     import org.opendaylight.aaa.cert.api.ICertificateManager;
540     import org.opendaylight.controller.md.sal.binding.api.DataBroker;
541
542     public class UseCertManagerExampleProvider {
543       private final DataBroker dataBroker;
544       private final ICertificateManager caManager;
545
546       public EncSrvExampleProvider(final DataBroker dataBroker, final ICertificateManager caManager) {
547         this.dataBroker = dataBroker;
548         this.caManager = caManager;
549       }
550       public SSLEngine createSSLEngine() {
551         final SSLContext sslContext = caManager.getServerContext();
552         if (sslContext != null) {
553           final SSLEngine sslEngine = sslContext.createSSLEngine();
554           sslEngine.setEnabledCipherSuites(caManager.getCipherSuites());
555           // DO the Implementation
556           return sslEngine;
557         }
558       }
559       public void init() {
560           // TODO
561       }
562       public void close() {
563           // TODO
564       }
565     }
566
567 4. The Certificate Manager Service provides two main methods that are needed to
568    establish the *SSLEngine* object, *getServerContext()* and *getCipherSuites()*
569    as the above example shows. It also provides other methods such as
570    *getODLKeyStore()* and *getTrustKeyStore()* that gives access to the
571    OpenDaylight and Trust keystores.
572
573 5. Now the *ICertificateManager* need to be passed as an argument to the
574    *UseCertManagerExampleProvider* within the implementation bundle blueprint
575    configuration. The following example shows how:
576
577 .. code-block:: xml
578
579     <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
580       xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
581       odl:use-default-for-reference-types="true">
582       <reference id="dataBroker"
583         interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
584         odl:type="default" />
585       <reference id="aaaCertificateManager"
586         interface="org.opendaylight.aaa.cert.api.ICertificateManager"
587         odl:type="default-certificate-manager" />
588       <bean id="provider"
589         class="org.opendaylight.UseCertManagerExample.impl.UseCertManagerExampleProvider"
590         init-method="init" destroy-method="close">
591         <argument ref="dataBroker" />
592         <argument ref="aaaCertificateManager" />
593       </bean>
594     </blueprint>
595
596 6. After finishing the bundle implementation the feature module needs to be
597    updated to include the *aaa-cert* feature in its feature bundle pom.xml file.
598
599 .. code-block:: xml
600
601     <properties>
602       <aaa.version>0.5.0-SNAPSHOT</aaa.version>
603     </properties>
604     <dependency>
605       <groupId>org.opendaylight.aaa</groupId>
606       <artifactId>features-aaa</artifactId>
607       <version>${aaa.version}</version>
608       <classifier>features</classifier>
609       <type>xml</type>
610     </dependency>
611
612 7. Now, in the feature.xml file add the Certificate Manager Service feature and
613    its repository.
614
615 .. code-block:: xml
616
617     <repository>mvn:org.opendaylight.aaa/features-aaa/{VERSION}/xml/features</repository>
618
619 The Certificate Manager Service feature can be included inside the
620 implementation bundle feature as shown in the following example:
621
622 .. code-block:: xml
623
624     <feature name='odl-UseCertManagerExample' version='${project.version}'
625       description='OpenDaylight :: UseCertManagerExample'>
626       <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
627       <feature version='${aaa.version}'>odl-aaa-cert</feature>
628       <bundle>mvn:org.opendaylight.UseCertManagerExample/UseCertManagerExample-impl/{VERSION}</bundle>
629     </feature>
630
631 8. Now the project can be built and the OpenDaylight distribution started to
632    continue with the configuration process. See the User Guide for more details.
633
634 Encryption Service
635 ------------------
636
637 The **AAA Encryption Service** is used to encrypt the OpenDaylight users'
638 passwords and TLS communication certificates. This section shows how to use the
639 AAA Encryption Service with an OpenDaylight distribution project to encrypt data.
640
641 1. It is assumed that there exists an already created OpenDaylight distribution
642    project following `this guide
643    <https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Startup_Project_Archetype#Part_1_-_Build_with_a_simple_.27Example.27_module>`_.
644
645 2. In the implementation bundle the following artifact must be added to its
646    *pom.xml* file as dependency.
647
648 .. code-block:: xml
649
650     <dependency>
651       <groupId>org.opendaylight.aaa</groupId>
652       <artifactId>aaa-encrypt-service</artifactId>
653       <version>0.5.0-SNAPSHOT</version>
654     </dependency>
655
656 3. Using the provider class in the implementation bundle needs to define a
657    variable holding the Encryption Service as in the following example:
658
659 .. code-block:: java
660
661     import org.opendaylight.aaa.encrypt.AAAEncryptionService;
662     import org.opendaylight.controller.md.sal.binding.api.DataBroker;
663
664     public class EncSrvExampleProvider {
665     private final DataBroker dataBroker;
666       private final AAAEncryptionService encryService;
667
668       public EncSrvExampleProvider(final DataBroker dataBroker, final AAAEncryptionService encryService) {
669         this.dataBroker = dataBroker;
670         this.encryService = encryService;
671       }
672       public void init() {
673         // TODO
674       }
675       public void close() {
676         // TODO
677       }
678     }
679
680 The AAAEncryptionService can be used to encrypt and decrypt any data based on
681 project's needs.
682
683 4. Now the *AAAEncryptionService* needs to be passed as an argument to the
684    *EncSrvExampleProvider* within the implementation bundle blueprint
685    configuration. The following example shows how:
686
687 .. code-block:: xml
688
689     <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
690       xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
691       odl:use-default-for-reference-types="true">
692       <reference id="dataBroker"
693         interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
694         odl:type="default" />
695       <reference id="encryService" interface="org.opendaylight.aaa.encrypt.AAAEncryptionService"/>
696       <bean id="provider"
697         class="org.opendaylight.EncSrvExample.impl.EncSrvExampleProvider"
698         init-method="init" destroy-method="close">
699         <argument ref="dataBroker" />
700         <argument ref="encryService" />
701       </bean>
702     </blueprint>
703
704 5. After finishing the bundle implementation the feature module needs to be
705    updated to include the *aaa-encryption-service* feature in its feature bundle
706    pom.xml file.
707
708 .. code-block:: xml
709
710     <dependency>
711       <groupId>org.opendaylight.aaa</groupId>
712       <artifactId>features-aaa</artifactId>
713       <version>${aaa.version}</version>
714       <classifier>features</classifier>
715       <type>xml</type>
716     </dependency>
717
718 It is also necessary to add the *aaa.version* in the properties section:
719
720 .. code-block:: xml
721
722     <properties>
723       <aaa.version>0.5.0-SNAPSHOT</aaa.version>
724     </properties>
725
726 6. Now, in the feature.xml file add the Encryption Service feature and its
727    repository.
728
729 .. code-block:: xml
730
731     <repository>mvn:org.opendaylight.aaa/features-aaa/{VERSION}/xml/features</repository>
732
733 The Encryption Service feature can be included inside the implementation bundle
734 feature as shown in the following example:
735
736 .. code-block:: xml
737
738     <feature name='odl-EncSrvExample' version='${project.version}' description='OpenDaylight :: EncSrvExample'>
739       <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
740       <feature version='${aaa.version}'>odl-aaa-encryption-service</feature>
741       <feature version='${project.version}'>odl-EncSrvExample-api</feature>
742       <bundle>mvn:org.opendaylight.EncSrvExample/EncSrvExample-impl/{VERSION}</bundle>
743     </feature>
744
745 7. Now the project can be built and the OpenDaylight distribution started to
746    continue with the configuration process. See the User Guide for more details.