Project

General

Profile

CdmAuthorisationAndAccessControl » History » Version 68

Andreas Müller, 10/27/2021 12:27 AM

1 56 Andreas Kohlbecker
# CDM authorisation and access control
2 2 Andreas Kohlbecker
3
It is evident that the cdm library needs authorisation and access control. There are library methods which need to protected from unauthorised execution and there is also the data which is exposed by the library. Not all data should be visible to every user so a [[HibernateSpringAndRowlevelSecurity|row level access control]] is needed.
4
5 57 Andreas Kohlbecker
Further information can be found in:
6
7
* [[WorkshopRightsAndRoles2017-11| Workshop Rights & Roles 2017-11]]
8
9 2 Andreas Kohlbecker
10 4 Andreas Kohlbecker
_This page only is a brief note for now, compiled by a lot of copy paste from the java doc!_
11 52 Andreas Kohlbecker
12 56 Andreas Kohlbecker
{{>toc}}
13 18 Andreas Kohlbecker
14 59 Andreas Kohlbecker
## Roles and CdmAuthorities
15 19 Andreas Kohlbecker
16
#### Roles
17 20 Andreas Kohlbecker
18 52 Andreas Kohlbecker
Roles are defined in two places:
19 19 Andreas Kohlbecker
20 52 Andreas Kohlbecker
1. eu.etaxonomy.cdm.persistence.hibernate.permission.Role
21
  * ROLE_ADMIN
22 68 Andreas Müller
  * ROLE_PROJECT_MANAGER  (permission to modify server-side preferences, terms and vocabularies, ... this Role explicitly has NO overlap with ROLE_USER_MANAGER or ROLE_PUBLISH)
23 60 Andreas Kohlbecker
  * ROLE_USER_MANAGER (permission to modify User, Group, GrantedAuthority)
24
  * ROLE_PUBLISH (permission to modify the publish flag of Taxon, ...)
25 68 Andreas Müller
  * ROLE_REMOTING (permission to use the /remoting/** webservice, that is to connect the TaxEditor to a cdm instance, see #7972)
26 1 Andreas Kohlbecker
1. eu.etaxonomy.cdm.remote.config.MultiWebSecurityConfiguration
27 65 Andreas Kohlbecker
 * ROLE_MANAGE_CLIENT: this role is only granted to machine clients only and never to real persons, see [Web service access control](#Web-service-access-control)
28 20 Andreas Kohlbecker
29
#### CdmAuthority
30
31 21 Andreas Kohlbecker
A `CdmAuthority` consists basically of two parts which are separated by a dot character '.'.
32 20 Andreas Kohlbecker
33 21 Andreas Kohlbecker
* permissionClass: an `CdmPermissionClass` instance with represents a cdm type or a part of the cdm type hierarchy. The className is always represented as an upper case string.
34
* property: The `CdmAuthority` only applies to instances which satisfy the specified property. Interpretation is up to type specific voters.
35
* operation: a string which specifies a `Operation` on that set of cdm types
36 1 Andreas Kohlbecker
* targetUuid: The operation may be restricted to a specific cdm entity by adding the entity uuid to the operation. The uuid string is enclosed in curly brackets '{' , '}' and appended to the end of the operation.
37 20 Andreas Kohlbecker
38
Examples for permissionStrings:
39
40
~~~
41 41 Andreas Kohlbecker
 TAXONBASE.[CREATE]
42
 TAXONBASE.[READ]
43
 TAXONBASE.[UPDATE]
44
 TAXONBASE.[DELETE]
45
 TAXONBASE.[DELETE,CREATE,UPDATE,READ]
46
 DESCRIPTIONBASE.UPDATE]
47
 DESCRIPTIONELEMENTBASE(Ecology).UPDATE]
48 1 Andreas Kohlbecker
 TAXONNODE.UPDATE{20c8f083-5870-4cbd-bf56-c5b2b98ab6a7}
49
~~~
50 21 Andreas Kohlbecker
51 24 Andreas Kohlbecker
in contrast to CdmAuthorities there are more general role like the following listed below, all these roles are having the  role prefix `'ROLE_'` which is defined in the String Security RoleVoter class:
52
53
~~~
54
 ROLE_ADMIN
55
 ROLE_USER_MANAGER
56
~~~
57
58 43 Andreas Kohlbecker
### Permission Groups
59
60
Permission groups can usually created as needed. The group name should reflect semantics the nature of the permission group.
61
62
The cdm provides default permission groups which are created by the `FirstDataInserter` in case they do not yet exist. See #4082 (implement default permission groups) for implementation details. Currently the following default permission groups exist: 
63
64 66 Andreas Kohlbecker
#### Allow_for_all_taxa
65 1 Andreas Kohlbecker
66 66 Andreas Kohlbecker
* Default group, added by the `FirstDataInserter`
67
68
Grant users with the ability to work on all taxa in all classifications.
69
You may want to compine this group with **Editor** as far as no restriction on the taxa are mandatory. 
70
71 1 Andreas Kohlbecker
~~~
72 66 Andreas Kohlbecker
TAXONNODE.[CREATE,READ,UPDATE,DELETE]
73
~~~~
74
75
#### Editor
76
77
* Default group, added by the `FirstDataInserter`
78
79
Contains all Authorities which are required to be granted for general editing, except the Authority for a specific taxonomical group. In order to actually enable an Editor to edit something it must be associated with a TAXONNODE Authority, e.g: @TAXONNODE.[CREATE,UPDATE,DELETE,READ]{...@}. (===> **Allow_for_all_taxa**) Users which belong to this permission group are prohibited from toggling the publish-flag and from changing or deleting references and authors, but are able to create new ones. Once a 'Editor' has created a new Reference or Author the new entity is considered being still in the process of being created for some time even if the entity has already been saved to the database. See #4305 (newly created entities must stay editable even if a user only has the permission to create them) for implementation details on this feature.
80
81
~~~
82 43 Andreas Kohlbecker
REFERENCE.[CREATE,READ]
83
TAXONNAMEBASE.[CREATE,READ,UPDATE]
84
TEAMORPERSONBASE.[CREATE,READ]
85 1 Andreas Kohlbecker
TAXONBASE.[CREATE,UPDATE,DELETE,READ]
86 43 Andreas Kohlbecker
DESCRIPTIONBASE.[CREATE,UPDATE,DELETE,READ]
87 60 Andreas Kohlbecker
DESCRIPTIONELEMENTBASE.[CREATE,UPDATE,DELETE,READ]
88 43 Andreas Kohlbecker
ROLE_REMOTING
89 1 Andreas Kohlbecker
~~~
90
91 66 Andreas Kohlbecker
#### ProjectManager
92
93
* Default group, added by the `FirstDataInserter`
94
95
A permission group which enables a User to edit and delete entities which are of central importance for a whole project. Users which belong to this permission group are granted to edit and delete taxa, names, references, authors, terms and can toggle the publish-flag on taxa, specimens and occurrences.
96
97 43 Andreas Kohlbecker
~~~
98
REFERENCE.[UPDATE,DELETE]
99
TAXONNAMEBASE.[DELETE]
100
TEAMORPERSONBASE.[UPDATE,DELETE]
101 1 Andreas Kohlbecker
ROLE_PROJECT_MANAGER
102
~~~
103 66 Andreas Kohlbecker
104
#### Editor-Descriptions
105
106
107
* Custom group, needs to be added manually
108 1 Andreas Kohlbecker
109 67 Andreas Kohlbecker
Enables a User to work with structured descriptions in the "Matrix editor". 
110
Does not need to be combined with any other group like it is needed for **Editor** as long as the users only it to be working on specimen descriptions.
111 66 Andreas Kohlbecker
112
~~~
113
DESCRIPTIONBASE.[CREATE,READ,UPDATE,DELETE]
114
DESCRIPTIONELEMENTBASE.[CREATE,READ,UPDATE,DELETE]
115 1 Andreas Kohlbecker
ROLE_REMOTING
116
~~~
117 67 Andreas Kohlbecker
118
#### ProjectManager
119 66 Andreas Kohlbecker
120 43 Andreas Kohlbecker
121 21 Andreas Kohlbecker
### Authorisation control
122
123
Different approaches of authorisation control need to be used in order to implement all kinds of CRUD permissions:
124
125
* service layer: method `@PreAuthorize` annotations with Spring EL, e.g. UserService:
126
127
~~~
128 1 Andreas Kohlbecker
@PreAuthorize("#username == authentication.name or hasRole('ROLE_ADMIN')")
129 21 Andreas Kohlbecker
public void changePasswordForUser(String username, String newPassword) {
130 1 Andreas Kohlbecker
...
131 21 Andreas Kohlbecker
~~~
132
* UPDATE and CREATE of cdm instances is protected by a Hibernate interceptor, the `CdmSecurityHibernateInterceptor@. This interceptor implements the  @onSave()` and `onFlushDirty` methods and thus can control creation and updating of cdm objects. Hibernate calls these methods for any entity which needs to be persisted even if a save or update operations causes a cascading save of objects connected to the object graph which is being saved. **TODO** implement DELETE (#3079)
133
* READ permissions can not be implemented using the `CdmSecurityHibernateInterceptor@. Reasons: @onLoad()` is called just before an object is initialized, so the object has no uuid or anything else with would be needed to decide on principals authorisation. A row based access control mechanism is required, see [[HibernateSpringAndRowlevelSecurity]]
134 4 Andreas Kohlbecker
135 22 Andreas Kohlbecker
### Authorisation evaluation
136
137 1 Andreas Kohlbecker
138 63 Andreas Kohlbecker
One of the central classes for the evaluation of Roles and CdmAuthorities is the `CdmPermissionEvluator` with implements the `org.springframework.security.access.PermissionEvaluator`. The method `public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission)` will always return true if the authentication has the role `ROLE_ADMIN` otherwise decision making is delegated to a `AccessDecisionManager` which should be `UnanimousBasedUnrevocable`. This `AccessDecisionManager` polls all configured `AccessDecisionVoters` grants access if only grant (or abstain) votes were received. The `AccessDecisionManager` then asks the set of plugged in **`AccessDecisionVoter`s*. The cdm specific voters are found in the package eu.etaxonomy.cdm.persistence.hibernate.permission.voter. For actual configuration details please see the *persistence_security.xml** , here is an example: 
139 22 Andreas Kohlbecker
140 1 Andreas Kohlbecker
~~~
141 41 Andreas Kohlbecker
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBasedUnrevocable">
142 22 Andreas Kohlbecker
        <property name="decisionVoters">
143
            <list>
144
                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.GrantAlwaysVoter" />
145
                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.TaxonNodeVoter" />
146
                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.TaxonBaseVoter" />
147
                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.DescriptionBaseVoter" />
148
                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.DescriptionElementVoter" />
149
            </list>
150
        </property>
151
</bean>
152
153
<!--
154 41 Andreas Kohlbecker
    CdmPermissionEvaluator.hasPermissions() evaluates the CdmPermissions like TAXONNODE.[UPDATE]{20c8f083-5870-4cbd-bf56-c5b2b98ab6a7}
155 22 Andreas Kohlbecker
-->
156
<bean id="cdmPermissionEvaluator" class="eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionEvaluator">
157
    <property name="accessDecisionManager" ref="accessDecisionManager" />
158
</bean>
159
~~~
160 26 Andreas Kohlbecker
161
#### AccessDecisionVoters
162
163
As briefly described above, the AccessDecisionVoters are crucial for finding a decision on whether a user is allowed to perform an operation on a specific cdm object or class of cdm objects. The operations are the so called CRUD operations. This acronym refers to Create, Read, Update, Delete. 
164 1 Andreas Kohlbecker
165
A user can have one or multiple granted authorities, for more information on granted authorities please refer to the paragraph [[CdmAuthorisationAndAccessControl#CdmAuthority|CdmAuthority]] above. All voters will cast votes on all granted authorities a user has.
166 35 Andreas Kohlbecker
167 1 Andreas Kohlbecker
In the following we will just use the term voter as a short form for AccessDecisionVoter. 
168
169
Voters can cast three different vote:
170
171
* Allow
172
* Deny 
173
* Abstain
174
175
In order to make a access decision the AccessDecisionVoters are asked sequentially to cast their vote. If at least one voter casts _Deny_ the the whole operation will be denied. This behaviour is guaranteed by the `GrantAlwaysVoter` which will always cast an _Allow_.
176
177
All AccessDecisionVoters are responsible for a specific class of data entities and thus it will only cast an _Allow_ or _Deny_ vote when an operation on an object of this class is to be performed. If a voter is not responsible it will _Abstain_. If a voter "feels" not responsible it casts an _Abstain_. As a consequence of this concept everything is allowed unless a voter is responsible for a specific object class. Only in this case there is the potential that an operation will be denied.
178
179
Generally each of the voters will check if the user has a granted authority which matches the the operation and object. Voters can also perform additional checks (see TaxonNodeVoter, DescriptionElementVoter) which can take related objects into account (parent taxon nodes) or specific properties of of Objects (feature of description element).
180
181
List of existing AccessDecisionVoters in the order of their execution:
182
  
183
1. TaxonNodeVoter: 
184
  * responsible for TaxonNode
185
  * allows if voter is responsible for the object class in question and
186
    1. if the user has a granted authority for that specific object or for all objects of this class which matches the operation to be performed
187 61 Andreas Kohlbecker
    1. or if the user has a matching granted authority for any of the parent taxon nodes in the classification (e.g.: `TAXONNODE.UPDATE{20c8f083-5870-4cbd-bf56-c5b2b98ab6a7}`)
188 1 Andreas Kohlbecker
  * denies otherwise
189
1. TaxonBaseVoter:  
190
  * responsible for Taxon, Synonym
191
  * allows if voter is responsible for the object class in question and
192 61 Andreas Kohlbecker
    1. if the user has a granted authority for that specific object or for all objects of this class which matches the operation to be performed (e.g.: `TAXONBASE.UPDATE`)
193 1 Andreas Kohlbecker
  * denies otherwise
194
1. DescriptionBaseVoter:  
195
  * responsible for TaxonDescription, SpecimenDescription
196
  * allows if voter is responsible for the object class in question and
197 61 Andreas Kohlbecker
    1. if the user has a granted authority for that specific object or for all objects of this class which matches the operation to be performed (e.g.: `DESCRIPTIONBASE.UPDATE`)
198 1 Andreas Kohlbecker
  * denies otherwise
199
1. DescriptionElementVoter:  
200
  * responsible for all types of DescriptionElements
201
  * allows if voter is responsible for the object class in question and
202
    1. if the user has a granted authority for that specific object or for all objects of this class which matches the operation to be performed
203 61 Andreas Kohlbecker
    1. if the the operation to be preformed is specific to the Feature of the Description Element and if the _Property_ of one of the users granted authorities matches this Feature. (e.g.: `DESCRIPTIONELEMENTBASE(Ecology).[UPDATE]`)
204 1 Andreas Kohlbecker
  * denies otherwise
205
206 58 Andreas Kohlbecker
## Cdm Entity access control
207
208
### Type bases access control
209
210
This is defined through the general *CdmAuthotities* which are not referring to a specific entity uuid.
211
212
### Per entity access control
213
214
This is defined through the entity specific *CdmAuthotities* which referring to a specific entity by the uuid.
215
216
### Extended create permission problem
217
218
for e general discussion see #4305 (newly created entities must stay editable even if a user only has the permission to create them)  for details regarding the current implementation see #6867 (explicitely assign and revoke UPDATE & DELETE permission per enitity in the registration workflow). Problems with the current implementation: #7147, ...
219
220
221 1 Andreas Kohlbecker
## Web service access control
222
223
### Authentication
224
225
All web service end points which require authentication support http basic.
226
227
There are two sources of users:
228
229 56 Andreas Kohlbecker
**CDM users**: 
230
231
The users stored in the cdm database
232
233
**Global managing users**: 
234
 
235
Users stored in the Managing users properties file (`$HOME/.cdmLibrary/managing-users.properties`). This is a java properties file to populate the InMemoryUserDetailsManager in any of the cdm-remote instances with special global management users which are granted to access special web services. Among these are the /manage/ web services and those triggering long running tasks. Global management users have the role **ROLE_MANAGE_CLIENT** and will be available in each of the cdm-remote instances. Changes made to this file are applied after restarting a cdm instance. For implementation details please refer to #6248.
236
237
Web service endpoints accessible to global managing users:
238
239
* `/manage/**`
240
* `/**description/accumulateDistributions`
241 52 Andreas Kohlbecker
242
### Authorization
243
244
1. Classical spring security authorization as described above
245 53 Andreas Kohlbecker
1. OAuth2: see #6118 *evaluate spring-security-auth2 and spring-cloud-security as a framework for OAuth2*
246 52 Andreas Kohlbecker
247
## Use cases
248
249
 A. a specific **classification sub tree** is **publicly visible** that is it is _published_
250
 B. a specific **classification sub tree** must not be **publicly visible** in the data portal and thus must be also hidden in the web service responses
251
 C. a specific **classification sub tree** is only visible for users which have a specific **role** but the user is not granted to **edit** anything in/below it
252
 D. A user is only granted to **edit Descriptions** 
253
 E. A user is only granted to **edit DescriptionElements** of a specific _Feature_ 
254
 F. A user is only granted to **edit structured Descriptions** 
255
 G. Combinations of B, C and D, E must be possible
256
 H. Only users with the **roles** *Admin* or **Usermanager** or the user in question it self (if currently authenticated) are allowed to execute **change password** 
257
 I. Only users with the **roles** *Admin* or **Usermanager** are allowed to create or **edit** new users
258
259
~~~
260
<code class="rst">
261
Tabular summary of above use cases translated into roles:
262
263
===========  =========================  ======================================  ===============  =============================
264
\                                                                               what to protect
265
-----------  -------------------------  --------------------------------------  ----------------------------------------------
266
Usecase      Role                       authority string                        Entity            ServiceMethod
267
===========  =========================  ======================================  ===============  =============================
268
A.           Anonymous                  TaxonNode.[READ]{uuid}                     ...
269
B.           TaxGroupX_User             TaxonNode.[READ]{uuid}                     ...
270
C.           TaxGroupX_Editor           TaxonNode.[UPDATE]{uuid}                   ...
271
D.           DescriptionEditor		Description.[UPDATE]			 ...					
272
E.           DescriptionEditor		DescriptioElement(Ecology).[UPDATE]        ...					
273
H.           Admin, Usermanager                                                                  UserService.changePassword()
274
===========  =========================  ======================================  ===============  =============================
275
276
*Anonymous* means not authenticated  
277
278
~~~
279
280
 **Special cases:** 
281 1 Andreas Kohlbecker
282 62 Andreas Kohlbecker
* **`TaxonNames`** can potentially be shared between different taxa, thus a situation may occur where a user has grants to edit taxon A but not for taxon B, but both taxa are sharing the same name. How will we handle this situation, should the name be cloned when the user starts editing taxon A, so that taxon A has another name entity than taxon B after the user saved the latest changes?
283
* The same problem as described above for TaxonNames also accounts for *`References`*, but in this case the problem is more severe since references are very often part of multiple taxon names.