Merge "Remove the aaa-authn-federation bundle artifacts"
[aaa.git] / README.md
1 ## Opendaylight AAA
2
3 This project is aimed at providing a flexible, pluggable framework with out-of-the-box capabilities for Authentication, Authorization and Accounting.
4
5 ## Caveats
6 The following caveats are applicable to the current AAA implementation:
7  - The database (H2) used by ODL AAA Authentication store is not-cluster enabled. When deployed in a clustered environment each node needs to have its AAA
8  user file synchronised using out of band means.
9
10 ## Quick Start
11
12 ### Building
13
14 *Prerequisite:*  The followings are required for building AAA:
15
16 - Maven 3.3.9+
17 - JDK8
18
19 Get the code:
20
21     git clone https://git.opendaylight.org/gerrit/aaa
22
23 Build it:
24
25     cd aaa && mvn clean install
26
27 ### Installing
28
29 AAA is automatically installed upon installation of odl-restconf.  If you are using AAA from a non-RESTCONF context, you can install the necessary javax.servlet.Filter(s) through the following command:
30
31         feature:install odl-aaa-shiro
32
33 ### Protecting your REST/RestConf resources
34
35 Add the AAA `AAAShiroFilter` filter to your REST resource (RESTconf example):
36
37     <servlet>
38         <servlet-name>JAXRSRestconf</servlet-name>
39         <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
40         <init-param>
41             <param-name>javax.ws.rs.Application</param-name>
42             <param-value>org.opendaylight.controller.sal.rest.impl.RestconfApplication</param-value>
43         </init-param>
44         <!-- Token Auth Filter -->
45         <init-param>
46             <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
47             <param-value>
48                 org.opendaylight.aaa.shiro.filters.AAAShiroFilter
49             </param-value>
50         </init-param>
51         <load-on-startup>1</load-on-startup>
52     </servlet>
53
54 Rebuild and re-install your REST resource.
55
56 ### Running
57
58 Once the installation finishes, one can authenticates with the Opendaylight controller by presenting a username/password and a domain name (scope) to be logged into:
59
60     curl -s -d 'grant_type=password&username=admin&password=admin&scope=sdn' http://<controller>:<port>/oauth2/token
61
62 Upon successful authentication, the controller returns an access token with a configurable expiration in seconds, something similar to the followings:
63
64     {"expires_in":3600,"token_type":"Bearer","access_token":"d772d85e-34c7-3099-bea5-cfafd3c747cb"}
65
66 The access token can then be used to access protected resources on the controller by passing it along in the standard HTTP Authorization header with the resource request.  Example:
67
68     curl -s -H 'Authorization: Bearer d772d85e-34c7-3099-bea5-cfafd3c747cb' http://<controller>:<port>/restconf/operational/opendaylight-inventory:nodes
69
70 ## Framework Overview
71
72 ### Authentication
73
74 AAA supports 2 main authentication use-cases:  *direct* and *federated* authentication, with direct authentication being the simpler to deploy (i.e., no external system dependency) and hence being the out-of-the-box authentication mechanism.   
75
76 #### Direct
77
78 In this use-case, a user presents some credentials (e.g., username/password) directly to the Opendaylight (ODL) controller token endpoint `/oauth2/token` and receives an access token, which then can be used to access protected resources on the controller, similar to the example we saw in the Quickstart section: 
79
80 ![](https://wiki.opendaylight.org/images/c/cc/Direct_authn.png)
81
82 #### Federated
83
84 In the federated use-case, the responsibility of authentication is delegated to a third-party IdP (perhaps, an enterprise-level IdP): 
85
86 ![](https://wiki.opendaylight.org/images/f/fd/Federated_authn1.png)
87
88 In the above use-case, the user authenticates with a third-party IdP (username/password is shown as an example, but it could be anything that the IdP supports, such as MFA, OTP, etc...).  Upon successful authentication, the IdP  returns back a claim about the identity of that user.  The claim is then submitted to the Opendaylight token endpoint in exchange for an access token that can be used to access protected resources on the controller.  The IdP claim must be mapped into a corresponding ODL claim (user/domain/role) before an access token can be granted.
89
90 The Opendaylight controller comes with SSSD-based claim support, but other types of claim support can be also added with their implementation of the `org.opendaylight.aaa.api.ClaimAuth` API.
91
92 We can also take federation one step further and delegate token management and optionally part of the authorization responsibility to the third-party IdP:
93
94 ![](https://wiki.opendaylight.org/images/2/22/Federated_authn2.png)
95
96 In this case, we use the IdP token directly as an access token to access protected resources on the controller.  The controller maintains only enough information needed for access control.  Validation of the token is performed by implementation of the `org.opendaylight.aaa.api.TokenAuth` API and can be daisy-chained as resource filters on the controller, with the last filter being the controller's built-in  `org.opendaylight.aaa.sts.DirectTokenAuthFilter` to properly register the authentication context.
97
98 ### Authorization & Access Control
99
100 ODL supports two authorization engines at present, both of which are roughly similar in behavior.  Namely, the two authorization engines are the MDSALDynamicAuthorizationFilter(1) and the RolesAuthorizationFilter(2).  For several reasons explained further in this documentation, we STRONGLY encourage you to use the MDSALDyanmicAuthorizationFilter(1) approach over the RolesAuthorizationFilter(2).
101
102 1) MDSALDyanmicAuthorizationFilter
103
104 The MDSALDynamicAuthorizationFilter is a mechanism used to restrict access to partcular URL endpoint patterns.  Users may define a list of policies that are insertion-ordered.  Order matters for the list of policies, since the first matching policy is applied.  This choice was made to emulate behavior of the Apache Shiro RolesAuthorizationFilter.
105
106 A policy is a key/value pair, where the key is a resource (i.e., a "url pattern") and the value is a list of permissions for the resource.  The following describes the various elements of a policy:
107
108 resource:          The resource is a string url pattern as outlined by Apache Shiro.  For more information, see http://shiro.apache.org/web.html.
109 description:       An optional description of the URL endpoint and why it is being secured.
110 permissions list:  A list of permissions for a particular policy.  If more than one permission exists in the permissions list, the permissions are evaluted using logical "OR".
111
112 A permission describes the prerequisites to perform HTTP operations on a particular endpoint.  The following describes the various elements of a permission:
113
114 role:              The role required to access the target URL endpoint.
115 actions list:      A leaf-list of HTTP permissions that are allowed for a Subject possessing the required role.
116
117 ---------
118 Example:
119
120 To limit access to the modules endpoint, issue the following:
121
122 HTTP Operation:    put
123 URL:               /restconf/config/aaa:http-authorization/policies
124 Headers:
125     Content-Tye:       application/json
126     Accept:            application/json
127
128 Body:
129
130 {
131   "aaa:policies": {
132     "aaa:policies": [
133       {
134         "aaa:resource": "/restconf/modules/**",
135         "aaa:permissions": [
136           {
137             "aaa:role": "admin",
138             "aaa:actions": [
139               "get","post","put","patch","delete"
140             ]
141           }
142         ]
143       }
144     ]
145   }
146 }
147 --------
148 The above example locks down access to the modules endpoint (and any URLS available past modules) to the "admin" role.  Thus, an attempt from the OOB admin user will succeed with 2XX HTTP status code, while an attempt from the OOB "user" user will fail with HTTP status code 401, as the "user" user is not granted the "admin" role.
149
150 NOTE:  "aaa:resource" value starts with "/restconf".  Unlike the RolesAuthorizationFilter ("roles" in shiro.ini) which is relative to the ServletContext, The MDSALDyanmicAuthorizationFilter is relative to the Servlet Root (i.e., "/").  This is superior, as it is more specific and does not allow for ambiguity.
151
152 2) shiro.ini urls section Authorization roles filter (i.e., "RolesAuthorizationFilter"). [DEPRECATED]
153
154 Authorization is implemented via the aaa-shiro modules.  RolesAuthorizationFilter (roles filter) is limited purely to RESTCONF (HTTP) and does not focus on MD-SAL.
155
156 More information on how to configure authorization can be found on the Apache Shiro website:
157
158     http://shiro.apache.org/web.html
159
160 NOTE:  Use of shiro.ini urls section to define roles requirements is discouraged!  This is due to the fact that shiro.ini changes are only recognized on servlet container startup.  Changes to shiro.ini are only honored upon restart.
161
162 NOTE:  Use of shiro.ini urls section to define roles requirements is discouraged!  This is due to the fact that url patterns are matched relative to the servlet context.  This leaves room for ambiguity, since many endpoints may match (i.e., "/restconf/modules" and "/auth/modules" would both match a "/modules/**" rule).
163
164 ### Accounting
165
166 Accounting is handled through the standard slf4j logging mechanisms used by the rest of OpenDaylight.  Thus, one can control logging verbosity through manipulating the log levels for individual packages and classes directly through the karaf shell, JMX, or etc/org.ops4j.pax.logging.cfg.  In normal operations, the default levels exposed do not provide much information about AAA services;  this is due to the fact that logging can severely degrade performance.
167
168 Two noteworthy logging activities are:
169 1) Enable debugging logging
170 2) Enable successful/unsuccessful authentication attempts logging
171
172 #### Enable Debugging Logging
173
174 For debugging purposes (i.e., to enable maximum verbosity), issue the following command:
175
176 karaf> log:set TRACE org.opendaylight.aaa
177
178 #### Enable Successful/Unsuccessful Authentication Attempts Logging
179 By default, successful/unsuccessful authentication attempts are NOT logged.  This is due to the fact that logging can severely decrease REST performance.  To enable logging of successful/unsuccessful REST attempts, issue the following command:
180
181 karaf> log:set DEBUG org.opendaylight.aaa.shiro.filters.AuthenticationListener
182
183 It is possible to add custom AuthenticationListener(s) to the Shiro based configuration, allowing different ways to listen for successful/unsuccessful authentication attempts.  Custom AuthenticationListener(s) must implement the org.apache.shiro.authc.AuthenticationListener interface.