38cc7cb0833f3f0403c7a53526489c7f3b9d44f4
[docs.git] / docs / user-guide / authentication-and-authorization-services.rst
1 Authentication, Authorization and Accounting (AAA) Services
2 ===========================================================
3
4 The Boron AAA services are based on the Apache Shiro Java Security
5 Framework. The main configuration file for AAA is located at
6 “etc/shiro.ini” relative to the ODL karaf home directory.
7
8 Terms And Definitions
9 ---------------------
10
11 Token
12     A claim of access to a group of resources on the controller
13
14 Domain
15     A group of resources, direct or indirect, physical, logical, or
16     virtual, for the purpose of access control. ODL recommends using the
17     default “sdn" domain in the Boron release.
18
19 User
20     A person who either owns or has access to a resource or group of
21     resources on the controller
22
23 Role
24     Opaque representation of a set of permissions, which is merely a
25     unique string as admin or guest
26
27 Credential
28     Proof of identity such as username and password, OTP, biometrics, or
29     others
30
31 Client
32     A service or application that requires access to the controller
33
34 Claim
35     A data set of validated assertions regarding a user, e.g. the role,
36     domain, name, etc.
37
38 How to enable AAA
39 -----------------
40
41 AAA is enabled through installing the odl-aaa-shiro feature.
42 odl-aaa-shiro is automatically installed as part of the odl-restconf
43 offering.
44
45 How to disable AAA
46 ------------------
47
48 Edit the “etc/shiro.ini” file and replace the following:
49
50 ::
51
52     /** = authcBasic
53
54 with
55
56 ::
57
58     /** = anon
59
60 Then restart the karaf process.
61
62 How application developers can leverage AAA to provide servlet security
63 -----------------------------------------------------------------------
64
65 In order to provide security to a servlet, add the following to the
66 servlet’s web.xml file as the first filter definition:
67
68 ::
69
70     <context-param>
71       <param-name>shiroEnvironmentClass</param-name>
72       <param-value>org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment</param-value>
73     </context-param>
74
75     <listener>
76         <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
77     </listener>
78
79     <filter>
80         <filter-name>ShiroFilter</filter-name>
81         <filter-class>org.opendaylight.aaa.shiro.filters.AAAShiroFilter</filter-class>
82     </filter>
83
84     <filter-mapping>
85         <filter-name>AAAShiroFilter</filter-name>
86         <url-pattern>/*</url-pattern>
87     </filter-mapping>
88
89 .. note::
90
91     It is very important to place this AAAShiroFilter as the first
92     javax.servlet.Filter, as Jersey applies Filters in the order they
93     appear within web.xml. Placing the AAAShiroFilter first ensures
94     incoming HTTP/HTTPS requests have proper credentials before any
95     other filtering is attempted.
96
97 AAA Realms
98 ----------
99
100 AAA plugin utilizes realms to support pluggable authentication &
101 authorization schemes. There are two parent types of realms:
102
103 -  AuthenticatingRealm
104
105    -  Provides no Authorization capability.
106
107    -  Users authenticated through this type of realm are treated
108       equally.
109
110 -  AuthorizingRealm
111
112    -  AuthorizingRealm is a more sophisticated AuthenticatingRealm,
113       which provides the additional mechanisms to distinguish users
114       based on roles.
115
116    -  Useful for applications in which roles determine allowed
117       cabilities.
118
119 ODL Contains Four Implementations
120
121 -  TokenAuthRealm
122
123    -  An AuthorizingRealm built to bridge the Shiro-based AAA service
124       with the h2-based AAA implementation.
125
126    -  Exposes a RESTful web service to manipulate IdM policy on a
127       per-node basis. If identical AAA policy is desired across a
128       cluster, the backing data store must be synchronized using an out
129       of band method.
130
131    -  A python script located at “etc/idmtool” is included to help
132       manipulate data contained in the TokenAuthRealm.
133
134    -  Enabled out of the box.
135
136 -  ODLJndiLdapRealm
137
138    -  An AuthorizingRealm built to extract identity information from IdM
139       data contained on an LDAP server.
140
141    -  Extracts group information from LDAP, which is translated into ODL
142       roles.
143
144    -  Useful when federating against an existing LDAP server, in which
145       only certain types of users should have certain access privileges.
146
147    -  Disabled out of the box.
148
149 -  ODLJndiLdapRealmAuthNOnly
150
151    -  The same as ODLJndiLdapRealm, except without role extraction.
152       Thus, all LDAP users have equal authentication and authorization
153       rights.
154
155    -  Disabled out of the box.
156
157 -  ActiveDirectoryRealm
158
159 .. note::
160
161     More than one Realm implementation can be specified. Realms are
162     attempted in order until authentication succeeds or all realm
163     sources are exhausted.
164
165 TokenAuthRealm Configuration
166 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
167
168 TokenAuthRealm stores IdM data in an h2 database on each node. Thus,
169 configuration of a cluster currently requires configuring the desired
170 IdM policy on each node. There are two supported methods to manipulate
171 the TokenAuthRealm IdM configuration:
172
173 -  idmtool Configuration
174
175 -  RESTful Web Service Configuration
176
177 idmtool Configuration
178 ^^^^^^^^^^^^^^^^^^^^^
179
180 A utility script located at “etc/idmtool” is used to manipulate the
181 TokenAuthRealm IdM policy. idmtool assumes a single domain (sdn), since
182 multiple domains are not leveraged in the Boron release. General usage
183 information for idmtool is derived through issuing the following
184 command:
185
186 ::
187
188     $ python etc/idmtool -h
189     usage: idmtool [-h] [--target-host TARGET_HOST]
190                    user
191                    {list-users,add-user,change-password,delete-user,list-domains,list-roles,add-role,delete-role,add-grant,get-grants,delete-grant}
192                    ...
193
194     positional arguments:
195       user                  username for BSC node
196       {list-users,add-user,change-password,delete-user,list-domains,list-roles,add-role,delete-role,add-grant,get-grants,delete-grant}
197                             sub-command help
198         list-users          list all users
199         add-user            add a user
200         change-password     change a password
201         delete-user         delete a user
202         list-domains        list all domains
203         list-roles          list all roles
204         add-role            add a role
205         delete-role         delete a role
206         add-grant           add a grant
207         get-grants          get grants for userid on sdn
208         delete-grant        delete a grant
209
210     optional arguments:
211       -h, --help            show this help message and exit
212       --target-host TARGET_HOST
213                             target host node
214
215 Add a user
216 ''''''''''
217
218 ::
219
220     python etc/idmtool admin add-user newUser
221     Password:
222     Enter new password:
223     Re-enter password:
224     add_user(admin)
225
226     command succeeded!
227
228     json:
229     {
230         "description": "",
231         "domainid": "sdn",
232         "email": "",
233         "enabled": true,
234         "name": "newUser",
235         "password": "**********",
236         "salt": "**********",
237         "userid": "newUser@sdn"
238     }
239
240 .. note::
241
242     AAA redacts the password and salt fields for security purposes.
243
244 Delete a user
245 '''''''''''''
246
247 ::
248
249     $ python etc/idmtool admin delete-user newUser@sdn
250     Password:
251     delete_user(newUser@sdn)
252
253     command succeeded!
254
255 List all users
256 ''''''''''''''
257
258 ::
259
260     $ python etc/idmtool admin list-users
261     Password:
262     list_users
263
264     command succeeded!
265
266     json:
267     {
268         "users": [
269             {
270                 "description": "user user",
271                 "domainid": "sdn",
272                 "email": "",
273                 "enabled": true,
274                 "name": "user",
275                 "password": "**********",
276                 "salt": "**********",
277                 "userid": "user@sdn"
278             },
279             {
280                 "description": "admin user",
281                 "domainid": "sdn",
282                 "email": "",
283                 "enabled": true,
284                 "name": "admin",
285                 "password": "**********",
286                 "salt": "**********",
287                 "userid": "admin@sdn"
288             }
289         ]
290     }
291
292 Change a user’s password
293 ''''''''''''''''''''''''
294
295 ::
296
297     $ python etc/idmtool admin change-password admin@sdn
298     Password:
299     Enter new password:
300     Re-enter password:
301     change_password(admin)
302
303     command succeeded!
304
305     json:
306     {
307         "description": "admin user",
308         "domainid": "sdn",
309         "email": "",
310         "enabled": true,
311         "name": "admin",
312         "password": "**********",
313         "salt": "**********",
314         "userid": "admin@sdn"
315     }
316
317 Add a role
318 ''''''''''
319
320 ::
321
322     $ python etc/idmtool admin add-role network-admin
323     Password:
324     add_role(network-admin)
325
326     command succeeded!
327
328     json:
329     {
330         "description": "",
331         "domainid": "sdn",
332         "name": "network-admin",
333         "roleid": "network-admin@sdn"
334     }
335
336 Delete a role
337 '''''''''''''
338
339 ::
340
341     $ python etc/idmtool admin delete-role network-admin@sdn
342     Password:
343     delete_role(network-admin@sdn)
344
345     command succeeded!
346
347 List all roles
348 ''''''''''''''
349
350 ::
351
352     $ python etc/idmtool admin list-roles
353     Password:
354     list_roles
355
356     command succeeded!
357
358     json:
359     {
360         "roles": [
361             {
362                 "description": "a role for admins",
363                 "domainid": "sdn",
364                 "name": "admin",
365                 "roleid": "admin@sdn"
366             },
367             {
368                 "description": "a role for users",
369                 "domainid": "sdn",
370                 "name": "user",
371                 "roleid": "user@sdn"
372             }
373         ]
374     }
375
376 List all domains
377 ''''''''''''''''
378
379 ::
380
381     $ python etc/idmtool admin list-domains
382     Password:
383     list_domains
384
385     command succeeded!
386
387     json:
388     {
389         "domains": [
390             {
391                 "description": "default odl sdn domain",
392                 "domainid": "sdn",
393                 "enabled": true,
394                 "name": "sdn"
395             }
396         ]
397     }
398
399 Add a grant
400 '''''''''''
401
402 ::
403
404     $ python etc/idmtool admin add-grant user@sdn admin@sdn
405     Password:
406     add_grant(userid=user@sdn,roleid=admin@sdn)
407
408     command succeeded!
409
410     json:
411     {
412         "domainid": "sdn",
413         "grantid": "user@sdn@admin@sdn@sdn",
414         "roleid": "admin@sdn",
415         "userid": "user@sdn"
416     }
417
418 Delete a grant
419 ''''''''''''''
420
421 ::
422
423     $ python etc/idmtool admin delete-grant user@sdn admin@sdn
424     Password:
425     http://localhost:8181/auth/v1/domains/sdn/users/user@sdn/roles/admin@sdn
426     delete_grant(userid=user@sdn,roleid=admin@sdn)
427
428     command succeeded!
429
430 Get grants for a user
431 '''''''''''''''''''''
432
433 ::
434
435     python etc/idmtool admin get-grants admin@sdn
436     Password:
437     get_grants(admin@sdn)
438
439     command succeeded!
440
441     json:
442     {
443         "roles": [
444             {
445                 "description": "a role for users",
446                 "domainid": "sdn",
447                 "name": "user",
448                 "roleid": "user@sdn"
449             },
450             {
451                 "description": "a role for admins",
452                 "domainid": "sdn",
453                 "name": "admin",
454                 "roleid": "admin@sdn"
455             }
456         ]
457     }
458
459 RESTful Web Service
460 ^^^^^^^^^^^^^^^^^^^
461
462 The TokenAuthRealm IdM policy is fully configurable through a RESTful
463 web service. Full documentation for manipulating AAA IdM data is located
464 online (https://wiki.opendaylight.org/images/0/00/AAA_Test_Plan.docx),
465 and a few examples are included in this guide:
466
467 Get All Users
468 '''''''''''''
469
470 ::
471
472     curl -u admin:admin http://localhost:8181/auth/v1/users
473     OUTPUT:
474     {
475         "users": [
476             {
477                 "description": "user user",
478                 "domainid": "sdn",
479                 "email": "",
480                 "enabled": true,
481                 "name": "user",
482                 "password": "**********",
483                 "salt": "**********",
484                 "userid": "user@sdn"
485             },
486             {
487                 "description": "admin user",
488                 "domainid": "sdn",
489                 "email": "",
490                 "enabled": true,
491                 "name": "admin",
492                 "password": "**********",
493                 "salt": "**********",
494                 "userid": "admin@sdn"
495             }
496         ]
497     }
498
499 Create a User
500 '''''''''''''
501
502 ::
503
504     curl -u admin:admin -X POST -H "Content-Type: application/json" --data-binary @./user.json http://localhost:8181/auth/v1/users
505     PAYLOAD:
506     {
507         "name": "ryan",
508         "userid": "ryan@sdn",
509         "password": "ryan",
510         "domainid": "sdn",
511         "description": "Ryan's User Account",
512         "email": "ryandgoulding@gmail.com"
513     }
514
515     OUTPUT:
516     {
517         "userid":"ryan@sdn",
518         "name":"ryan",
519         "description":"Ryan's User Account",
520         "enabled":true,
521         "email":"ryandgoulding@gmail.com",
522         "password":"**********",
523         "salt":"**********",
524         "domainid":"sdn"
525     }
526
527 Create an OAuth2 Token For Admin Scoped to SDN
528 ''''''''''''''''''''''''''''''''''''''''''''''
529
530 ::
531
532     curl -d 'grant_type=password&username=admin&password=a&scope=sdn' http://localhost:8181/oauth2/token
533
534     OUTPUT:
535     {
536         "expires_in":3600,
537         "token_type":"Bearer",
538         "access_token":"5a615fbc-bcad-3759-95f4-ad97e831c730"
539     }
540
541 Use an OAuth2 Token
542 '''''''''''''''''''
543
544 ::
545
546     curl -H "Authorization: Bearer 5a615fbc-bcad-3759-95f4-ad97e831c730" http://localhost:8181/auth/v1/domains
547     {
548         "domains":
549         [
550             {
551                 "domainid":"sdn",
552                 "name":"sdn”,
553                 "description":"default odl sdn domain",
554                 "enabled":true
555             }
556         ]
557     }
558
559 ODLJndiLdapRealm Configuration
560 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
561
562 LDAP integration is provided in order to externalize identity
563 management. To configure LDAP parameters, modify "etc/shiro.ini"
564 parameters to include the ODLJndiLdapRealm:
565
566 ::
567
568     # ODL provides a few LDAP implementations, which are disabled out of the box.
569     # ODLJndiLdapRealm includes authorization functionality based on LDAP elements
570     # extracted through and LDAP search.  This requires a bit of knowledge about
571     # how your LDAP system is setup.  An example is provided below:
572     ldapRealm = org.opendaylight.aaa.shiro.realm.ODLJndiLdapRealm
573     ldapRealm.userDnTemplate = uid={0},ou=People,dc=DOMAIN,dc=TLD
574     ldapRealm.contextFactory.url = ldap://<URL>:389
575     ldapRealm.searchBase = dc=DOMAIN,dc=TLD
576     ldapRealm.ldapAttributeForComparison = objectClass
577     ldapRealm.groupRolesMap = "Person":"admin"
578     # ...
579     # further down in the file...
580     # Stacked realm configuration;  realms are round-robbined until authentication succeeds or realm sources are exhausted.
581     securityManager.realms = $tokenAuthRealm, $ldapRealm
582
583 This configuration allows federation with an external LDAP server, and
584 the user’s ODL role parameters are mapped to corresponding LDAP
585 attributes as specified by the groupRolesMap. Thus, an LDAP operator can
586 provision attributes for LDAP users that support different ODL role
587 structures.
588
589 ODLJndiLdapRealmAuthNOnly Configuration
590 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
591
592 Edit the "etc/shiro.ini" file and modify the following:
593
594 ::
595
596     ldapRealm = org.opendaylight.aaa.shiro.realm.ODLJndiLdapRealm
597     ldapRealm.userDnTemplate = uid={0},ou=People,dc=DOMAIN,dc=TLD
598     ldapRealm.contextFactory.url = ldap://<URL>:389
599     # ...
600     # further down in the file...
601     # Stacked realm configuration;  realms are round-robbined until authentication succeeds or realm sources are exhausted.
602     securityManager.realms = $tokenAuthRealm, $ldapRealm
603
604 This is useful for setups where all LDAP users are allowed equal access.
605
606 Token Store Configuration Parameters
607 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
608
609 Edit the file “etc/opendaylight/karaf/08-authn-config.xml” and edit the
610 following: .\ **timeToLive**: Configure the maximum time, in
611 milliseconds, that tokens are to be cached. Default is 360000. Save the
612 file.
613
614 Authorization Configuration
615 ---------------------------
616
617 Shiro-Based Authorization
618 ~~~~~~~~~~~~~~~~~~~~~~~~~
619
620 OpenDaylight AAA has support for Role Based Access Control based on the
621 Apache Shiro permissions system. Configuration of the authorization
622 system is done offline; authorization currently cannot be configured
623 after the controller is started. Thus, Authorization in this
624 release is aimed towards supporting coarse-grained security policies,
625 with the aim to provide more robust configuration capabilities in the
626 future. Shiro-based Authorization is documented on the Apache Shiro
627 website (http://shiro.apache.org/web.html#Web-%7B%7B%5Curls%5C%7D%7D).
628
629 Enable “admin” Role Based Access to the IdMLight RESTful web service
630 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
631
632 Edit the “etc/shiro.ini” configuration file and add “/auth/v1/\ **=
633 authcBasic, roles[admin]” above the line “/** = authcBasic” within the
634 “urls” section.
635
636 ::
637
638     /auth/v1/** = authcBasic, roles[admin]
639     /** = authcBasic
640
641 This will restrict the idmlight rest endpoints so that a grant for admin
642 role must be present for the requesting user.
643
644 .. note::
645
646     The ordering of the authorization rules above is important!
647
648 AuthZ Broker Facade
649 ~~~~~~~~~~~~~~~~~~~
650
651 ODL includes an experimental Authorization Broker Facade, which allows
652 finer grained access control for REST endpoints. Since this feature was
653 not well tested in the Boron release, it is recommended to use the
654 Shiro-based mechanism instead, and rely on the Authorization Broker
655 Facade for POC use only.
656
657 AuthZ Broker Facade Feature Installation
658 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
659
660 To install the authorization broker facade, please issue the following
661 command in the karaf shell:
662
663 ::
664
665     feature:install odl-restconf odl-aaa-authz
666
667 Add an Authorization Rule
668 ^^^^^^^^^^^^^^^^^^^^^^^^^
669
670 The following shows how one might go about securing the controller so
671 that only admins can access restconf.
672
673 ::
674
675     curl -u admin:admin -H “Content-Type: application/xml” --data-binary @./rule.json http://localhost:8181/restconf/config/authorization-schema:simple-authorization/policies/RestConfService/
676     cat ./rule.json
677     {
678         "policies": {
679             "resource": "*",
680             "service":"RestConfService",
681             "role": "admin"
682         }
683     }
684
685 Accounting Configuration
686 ------------------------
687
688 All AAA logging is output to the standard karaf.log file.
689
690 ::
691
692     log:set TRACE org.opendaylight.aaa
693
694 This command enables the most verbose level of logging for AAA
695 components.
696