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