Project

General

Profile

Actions

CdmAuthorisationAndAccessControl » History » Revision 24

« Previous | Revision 24/70 (diff) | Next »
Andreas Kohlbecker, 09/25/2012 03:22 PM


Cdm authorisation and access control

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 row level access control is needed.

Questions

  1. Do we need a access control in the web service (cdmlib-remote) or is it sufficient to protect the service layer. As long web service controllers are not using DAO (cdmlib-persistence) methods directly it should not be necessary.

Use cases

A. a specific classification sub tree is publicly visible that is it is published

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

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

D. A user is only granted to edit Descriptions

E. A user is only granted to edit DescriptionElements of a specific Feature

F. A user is only granted to edit structured Descriptions

G. Combinations of B, C and D, E must be possible

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

I. Only users with the roles Admin or Usermanager are allowed to create or edit new users

<code class="rst">
Tabular summary of above use cases translated into roles:

===========  =========================  ======================================  ===============  =============================
\                                                                               what to protect
-----------  -------------------------  --------------------------------------  ----------------------------------------------
Usecase      Role                       authority string                        Entity            ServiceMethod
===========  =========================  ======================================  ===============  =============================
A.           Anonymous                  TaxonNode.READ{uuid}                     ...
B.           TaxGroupX_User             TaxonNode.READ{uuid}                     ...
C.           TaxGroupX_Editor           TaxonNode.UPDATE{uuid}                   ...
D.           DescriptionEditor      Description.UPDATE           ...                    
E.           DescriptionEditor      DescriptioElement(Ecology).UPDATE        ...                    
H.           Admin, Usermanager                                                                  UserService.changePassword()
===========  =========================  ======================================  ===============  =============================

*Anonymous* means not authenticated  

Special cases:

  • @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?

  • 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.

Implementation details

only a brief note for now, compiled by a lot of copy paste from the java doc:

Roles and CdmAuthorities

Roles

only one hard coded role: ROLE_ADMIN

CdmAuthority

A CdmAuthority consists basically of two parts which are separated by a dot character '.'.

  • 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.

  • property: The CdmAuthority only applies to instances which satisfy the specified property. Interpretation is up to type specific voters.

  • operation: a string which specifies a Operation on that set of cdm types

  • 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.

Examples for permissionStrings:

 TAXONBASE.CREATE
 TAXONBASE.READ
 TAXONBASE.UPDATE
 TAXONBASE.DELETE
 DESCRIPTIONBASE.UPDATE
 DESCRIPTIONELEMENTBASE(Ecology).UPDATE
 TAXONNODE.UPDATE{20c8f083-5870-4cbd-bf56-c5b2b98ab6a7}

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:

 ROLE_ADMIN
 ROLE_USER_MANAGER

Authorisation control

Different approaches of authorisation control need to be used in order to implement all kinds of CRUD permissions:

  • service layer: method @PreAuthorize annotations with Spring EL, e.g. UserService:
@PreAuthorize("#username == authentication.name or hasRole('ROLE_ADMIN')")
public void changePasswordForUser(String username, String newPassword) {
...
  • 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)

  • 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

Authorisation evaluation

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 decission making is delegated to a AccessDecisionManager which should be org.springframework.security.access.vote.UnanimousBased@. 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:

<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased">
        <property name="decisionVoters">
            <list>
                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.GrantAlwaysVoter" />
                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.TaxonNodeVoter" />
                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.TaxonBaseVoter" />
                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.DescriptionBaseVoter" />
                <bean class="eu.etaxonomy.cdm.persistence.hibernate.permission.voter.DescriptionElementVoter" />
            </list>
        </property>
</bean>

<!--
    CdmPermissionEvaluator.hasPermissions() evaluates the CdmPermissions like TAXONNODE.UPDATE{20c8f083-5870-4cbd-bf56-c5b2b98ab6a7}
-->
<bean id="cdmPermissionEvaluator" class="eu.etaxonomy.cdm.persistence.hibernate.permission.CdmPermissionEvaluator">
    <property name="accessDecisionManager" ref="accessDecisionManager" />
</bean>

Updated by Andreas Kohlbecker over 11 years ago · 24 revisions