1 Authentication, Authorization and Accounting (AAA) Services
2 ===========================================================
7 Authentication, Authorization and Accounting (AAA) is a term for a
8 framework controlling access to resources, enforcing policies to use
9 those resources and auditing their usage. These processes are the
10 fundamental building blocks for effective network management and security.
12 Authentication provides a way of identifying a user, typically by
13 having the user enter a valid user name and valid password before access
14 is granted. The process of authentication is based on each user having a unique
15 set of criteria for gaining access. The AAA framework compares a user's
16 authentication credentials with other user credentials stored in a database.
17 If the credentials match, the user is granted access to the network.
18 If the credentials don't match, authentication fails and access is denied.
20 Authorization is the process of finding out what an authenticated user is
21 allowed to do within the system, which tasks can do, which API can call, etc.
22 The authorization process determines whether the user has the authority
23 to perform such actions.
25 Accounting is the process of logging the activity of an authenticated user,
26 for example, the amount of data a user has sent and/or received during a
27 session, which APIs called, etc.
33 Authentication, Authorization and Accounting.
36 A claim of access to a group of resources on the controller.
39 A group of resources, direct or indirect, physical, logical, or
40 virtual, for the purpose of access control.
43 A person who either owns or has access to a resource or group of
44 resources on the controller.
47 Opaque representation of a set of permissions, which is merely a
48 unique string as admin or guest.
51 Proof of identity such as user name and password, OTP, biometrics, or
55 A service or application that requires access to the controller.
58 A data set of validated assertions regarding a user, e.g. the role,
64 Security Framework for AAA services
65 -----------------------------------
67 Since Boron release, the OpenDaylight's AAA services are based on the
68 `Apache Shiro <https://shiro.apache.org/>`_ Java Security Framework. The main
69 configuration file for AAA is located at “etc/shiro.ini” relative to the
70 OpenDaylight Karaf home directory.
76 AAA is enabled through installing the odl-aaa-shiro feature. The vast majority
77 of OpenDaylight's northbound APIs (and all RESTCONF APIs) are protected by AAA
78 by default when installing the +odl-restconf+ feature, since the odl-aaa-shiro
79 is automatically installed as part of them. In the cases that APIs are *not*
80 protected by AAA, this will be noted in the per-project release notes.
86 Edit the “etc/shiro.ini” file and replace the following:
98 Then restart the Karaf process.
103 AAA plugin utilizes the Shiro Realms to support pluggable authentication &
104 authorization schemes. There are two parent types of realms:
106 - AuthenticatingRealm
108 - Provides no Authorization capability.
110 - Users authenticated through this type of realm are treated
115 - AuthorizingRealm is a more sophisticated AuthenticatingRealm,
116 which provides the additional mechanisms to distinguish users
119 - Useful for applications in which roles determine allowed
122 OpenDaylight contains four implementations:
126 - An AuthorizingRealm built to bridge the Shiro-based AAA service
127 with the h2-based AAA implementation.
129 - Exposes a RESTful web service to manipulate IdM policy on a
130 per-node basis. If identical AAA policy is desired across a
131 cluster, the backing data store must be synchronized using an out
134 - A python script located at “etc/idmtool” is included to help
135 manipulate data contained in the TokenAuthRealm.
137 - Enabled out of the box. This is the realm configured by default.
141 - An AuthorizingRealm built to extract identity information from IdM
142 data contained on an LDAP server.
144 - Extracts group information from LDAP, which is translated into
147 - Useful when federating against an existing LDAP server, in which
148 only certain types of users should have certain access privileges.
150 - Disabled out of the box.
152 - ODLJndiLdapRealmAuthNOnly
154 - The same as ODLJndiLdapRealm, except without role extraction.
155 Thus, all LDAP users have equal authentication and authorization
158 - Disabled out of the box.
160 - ODLActiveDirectoryRealm
162 - Wraps the generic ActiveDirectoryRealm provided by Shiro. This allows for
163 enhanced logging as well as isolation of all realms in a single package,
164 which enables easier import by consuming servlets.
168 More than one Realm implementation can be specified. Realms are attempted
169 in order until authentication succeeds or all realm sources are exhausted.
178 The TokenAuthRealm is the default Authorization Realm deployed in OpenDaylight.
179 TokenAuthRealm uses a direct authentication mechanism as shown in the following
182 .. figure:: ./images/aaa/direct-authentication.png
183 :alt: TokenAuthRealm direct authentication mechanism
185 TokenAuthRealm direct authentication mechanism
187 A user presents some credentials (e.g., username/password) directly to the
188 OpenDaylight controller token endpoint /oauth2/token and receives an access
189 token, which then can be used to access protected resources on the controller.
191 Configuring TokenAuthRealm
192 ~~~~~~~~~~~~~~~~~~~~~~~~~~
194 The TokenAuthRealm stores IdM data in an h2 database on each node. Thus,
195 configuration of a cluster currently requires configuring the desired IdM policy
196 on each node. There are two supported methods to manipulate the TokenAuthRealm
199 - idmtool configuration tool
201 - RESTful Web Service configuration
206 A utility script located at “etc/idmtool” is used to manipulate the
207 TokenAuthRealm IdM policy. idmtool assumes a single domain, the default one
208 (sdn), since multiple domains are not supported in the Boron release. General
209 usage information for idmtool is derived through issuing the following command:
213 $ python etc/idmtool -h
214 usage: idmtool [-h] [--target-host TARGET_HOST]
216 {list-users,add-user,change-password,delete-user,list-domains,list-roles,add-role,delete-role,add-grant,get-grants,delete-grant}
219 positional arguments:
220 user username for BSC node
221 {list-users,add-user,change-password,delete-user,list-domains,list-roles,add-role,delete-role,add-grant,get-grants,delete-grant}
223 list-users list all users
225 change-password change a password
226 delete-user delete a user
227 list-domains list all domains
228 list-roles list all roles
230 delete-role delete a role
231 add-grant add a grant
232 get-grants get grants for userid on sdn
233 delete-grant delete a grant
236 -h, --help show this help message and exit
237 --target-host TARGET_HOST
245 python etc/idmtool admin add-user newUser
260 "password": "**********",
261 "salt": "**********",
262 "userid": "newUser@sdn"
267 AAA redacts the password and salt fields for security purposes.
274 $ python etc/idmtool admin delete-user newUser@sdn
276 delete_user(newUser@sdn)
285 $ python etc/idmtool admin list-users
295 "description": "user user",
300 "password": "**********",
301 "salt": "**********",
305 "description": "admin user",
310 "password": "**********",
311 "salt": "**********",
312 "userid": "admin@sdn"
317 Change a user’s password
318 ''''''''''''''''''''''''
322 $ python etc/idmtool admin change-password admin@sdn
326 change_password(admin)
332 "description": "admin user",
337 "password": "**********",
338 "salt": "**********",
339 "userid": "admin@sdn"
347 $ python etc/idmtool admin add-role network-admin
349 add_role(network-admin)
357 "name": "network-admin",
358 "roleid": "network-admin@sdn"
366 $ python etc/idmtool admin delete-role network-admin@sdn
368 delete_role(network-admin@sdn)
377 $ python etc/idmtool admin list-roles
387 "description": "a role for admins",
390 "roleid": "admin@sdn"
393 "description": "a role for users",
406 $ python etc/idmtool admin list-domains
416 "description": "default odl sdn domain",
429 $ python etc/idmtool admin add-grant user@sdn admin@sdn
431 add_grant(userid=user@sdn,roleid=admin@sdn)
438 "grantid": "user@sdn@admin@sdn@sdn",
439 "roleid": "admin@sdn",
448 $ python etc/idmtool admin delete-grant user@sdn admin@sdn
450 http://localhost:8181/auth/v1/domains/sdn/users/user@sdn/roles/admin@sdn
451 delete_grant(userid=user@sdn,roleid=admin@sdn)
455 Get grants for a user
456 '''''''''''''''''''''
460 python etc/idmtool admin get-grants admin@sdn
462 get_grants(admin@sdn)
470 "description": "a role for users",
476 "description": "a role for admins",
479 "roleid": "admin@sdn"
484 **Configuration using the RESTful Web Service**
485 ###############################################
487 The TokenAuthRealm IdM policy is fully configurable through a RESTful
488 web service. Full documentation for manipulating AAA IdM data is located
489 online (https://wiki.opendaylight.org/images/0/00/AAA_Test_Plan.docx),
490 and a few examples are included in this guide:
497 curl -u admin:admin http://localhost:8181/auth/v1/users
502 "description": "user user",
507 "password": "**********",
508 "salt": "**********",
512 "description": "admin user",
517 "password": "**********",
518 "salt": "**********",
519 "userid": "admin@sdn"
529 curl -u admin:admin -X POST -H "Content-Type: application/json" --data-binary @./user.json http://localhost:8181/auth/v1/users
533 "userid": "ryan@sdn",
536 "description": "Ryan's User Account",
537 "email": "ryandgoulding@gmail.com"
544 "description":"Ryan's User Account",
546 "email":"ryandgoulding@gmail.com",
547 "password":"**********",
552 Create an OAuth2 Token For Admin Scoped to SDN
553 ''''''''''''''''''''''''''''''''''''''''''''''
557 curl -d 'grant_type=password&username=admin&password=a&scope=sdn' http://localhost:8181/oauth2/token
562 "token_type":"Bearer",
563 "access_token":"5a615fbc-bcad-3759-95f4-ad97e831c730"
571 curl -H "Authorization: Bearer 5a615fbc-bcad-3759-95f4-ad97e831c730" http://localhost:8181/auth/v1/domains
578 "description":"default odl sdn domain",
584 **Token Store Configuration Parameters**
585 ########################################
587 Edit the file “etc/opendaylight/karaf/08-authn-config.xml” and edit the
588 following: .\ **timeToLive**: Configure the maximum time, in milliseconds,
589 that tokens are to be cached. Default is 360000. Save the file.
597 LDAP integration is provided in order to externalize identity
598 management. This configuration allows federation with an external LDAP server.
599 The user’s OpenDaylight role parameters are mapped to corresponding LDAP
600 attributes as specified by the groupRolesMap. Thus, an LDAP operator can
601 provision attributes for LDAP users that support different OpenDaylight role
604 Configuring ODLJndiLdapRealm
605 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
607 To configure LDAP parameters, modify "etc/shiro.ini"
608 parameters to include the ODLJndiLdapRealm:
612 # OpenDaylight provides a few LDAP implementations, which are disabled out of the box.
613 # ODLJndiLdapRealm includes authorization functionality based on LDAP elements
614 # extracted through and LDAP search. This requires a bit of knowledge about
615 # how your LDAP system is setup. An example is provided below:
616 ldapRealm = org.opendaylight.aaa.shiro.realm.ODLJndiLdapRealm
617 ldapRealm.userDnTemplate = uid={0},ou=People,dc=DOMAIN,dc=TLD
618 ldapRealm.contextFactory.url = ldap://<URL>:389
619 ldapRealm.searchBase = dc=DOMAIN,dc=TLD
620 ldapRealm.ldapAttributeForComparison = objectClass
621 ldapRealm.groupRolesMap = "Person":"admin"
623 # further down in the file...
624 # Stacked realm configuration; realms are round-robbined until authentication succeeds or realm sources are exhausted.
625 securityManager.realms = $tokenAuthRealm, $ldapRealm
627 ODLJndiLdapRealmAuthNOnly
628 ^^^^^^^^^^^^^^^^^^^^^^^^^
633 This is useful for setups where all LDAP users are allowed equal access.
635 Configuring ODLJndiLdapRealmAuthNOnly
636 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
638 Edit the "etc/shiro.ini" file and modify the following:
642 ldapRealm = org.opendaylight.aaa.shiro.realm.ODLJndiLdapRealm
643 ldapRealm.userDnTemplate = uid={0},ou=People,dc=DOMAIN,dc=TLD
644 ldapRealm.contextFactory.url = ldap://<URL>:389
646 # further down in the file...
647 # Stacked realm configuration; realms are round-robbined until authentication succeeds or realm sources are exhausted.
648 securityManager.realms = $tokenAuthRealm, $ldapRealm
650 Authorization Configuration
651 ---------------------------
653 OpenDaylight supports two authorization engines at present, both of which are
654 roughly similar in behavior:
656 - Shiro-Based Authorization
658 - MDAL-Based Dynamic Authorization
662 The preferred mechanism for configuring AAA Authentication is the
663 MDSAL-Based Dynamic Authorization. Read the following section.
665 Shiro-Based Static Authorization
666 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
668 OpenDaylight AAA has support for Role Based Access Control (RBAC) based
669 on the Apache Shiro permissions system. Configuration of the authorization
670 system is done off-line; authorization currently cannot be configured
671 after the controller is started. The Authorization provided by this mechanism
672 is aimed towards supporting coarse-grained security policies, the MDSAL-Based
673 mechanism allows for a more robust configuration capabilities. `Shiro-based
674 Authorization <http://shiro.apache.org/web.html#Web-%7B%7B%5Curls%5C%7D%7D>`_
675 describes how to configure the Authentication feature in detail.
679 The Shiro-Based Authorization that uses the *shiro.ini* URLs section to
680 define roles requirements is **deprecated** and **discouraged** since the
681 changes made to the file are only honored on a controller restart.
683 Shiro-Based Authorization is not **cluster-aware**, so the changes made on
684 the *shiro.ini* file have to be replicated on every controller instance
685 belonging to the cluster.
687 The URL patterns are matched relative to the Servlet context leaving room
688 for ambiguity, since many endpoints may match (i.e., "/restconf/modules" and
689 "/auth/modules" would both match a "/modules/\**" rule).
691 Enable “admin” Role Based Access to the IdMLight RESTful web service
692 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
694 Edit the “etc/shiro.ini” configuration file and add “/auth/v1/\**=
695 authcBasic, roles[admin]” above the line “/\** = authcBasic” within the
700 /auth/v1/** = authcBasic, roles[admin]
703 This will restrict the idmlight rest endpoints so that a grant for admin
704 role must be present for the requesting user.
708 The ordering of the authorization rules above is important!
710 MDSAL-Based Dynamic Authorization
711 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
712 The MDSAL-Based Dynamic authorization uses the MDSALDynamicAuthorizationFilter
713 engine to restrict access to particular URL endpoint patterns. Users may define
714 a list of policies that are insertion-ordered. Order matters for that list of
715 policies, since the first matching policy is applied. This choice was made to
716 emulate behavior of the Shiro-Based Authorization mechanism.
718 A **policy** is a key/value pair, where the key is a **resource**
719 (i.e., a "URL pattern") and the value is a list of **permissions** for the
720 resource. The following describes the various elements of a policy:
722 - **Resource**: the resource is a string URL pattern as outlined by
723 Apache Shiro. For more information, see http://shiro.apache.org/web.html.
725 - **Description**: an optional description of the URL endpoint and why it is
728 - **Permissions list**: a list of permissions for a particular policy. If more
729 than one permission exists in the permissions list they are evaluated using
730 logical "OR". A permission describes the prerequisites to perform HTTP
731 operations on a particular endpoint. The following describes the various
732 elements of a permission:
734 + **Role**: the role required to access the target URL endpoint.
735 + **Actions list**: a leaf-list of HTTP permissions that are allowed for a
736 Subject possessing the required role.
738 This an example on how to limit access to the modules endpoint:
743 put URL: /restconf/config/aaa:http-authorization/policies
745 headers: Content-Type: application/json Accept: application/json
750 [ { "aaa:resource": "/restconf/modules/**",
751 "aaa:permissions": [ { "aaa:role": "admin",
752 "aaa:actions": [ "get",
765 The above example locks down access to the modules endpoint (and any URLS
766 available past modules) to the "admin" role. Thus, an attempt from the OOB
767 *admin* user will succeed with 2XX HTTP status code, while an attempt from the
768 OOB *user* user will fail with HTTP status code 401, as the user *user* is not
769 granted the "admin" role.
771 Accounting Configuration
772 ------------------------
774 Accounting is handled through the standard slf4j logging mechanisms used by the
775 rest of OpenDaylight. Thus, one can control logging verbosity through
776 manipulating the log levels for individual packages and classes directly through
777 the Karaf console, JMX, or etc/org.ops4j.pax.logging.cfg. In normal operations,
778 the default levels exposed do not provide much information about AAA services;
779 this is due to the fact that logging can severely degrade performance.
781 All AAA logging is output to the standard karaf.log file. For debugging purposes
782 (i.e., to enable maximum verbosity), issue the following command:
786 log:set TRACE org.opendaylight.aaa
788 Enable Successful/Unsuccessful Authentication Attempts Logging
789 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
791 By default, successful/unsuccessful authentication attempts are NOT logged. This
792 is due to the fact that logging can severely decrease REST performance.
793 To enable logging of successful/unsuccessful REST attempts, issue the following
794 command in Karaf's console:
798 log:set DEBUG org.opendaylight.aaa.shiro.filters.AuthenticationListener
800 It is possible to add custom AuthenticationListener(s) to the Shiro-based
801 configuration, allowing different ways to listen for successful/unsuccessful
802 authentication attempts. Custom AuthenticationListener(s) must implement
803 the org.apache.shiro.authc.AuthenticationListener interface.