Security and Identity within the CDM Library

Table of Contents

Identity
Authentication
Authorization

The CDM Library uses the Spring Security sub-project as the basis of its security implementation. The best place to get information on using Spring Security is the project website.

Spring Security is based around a non-intrusive and non-invasive architecture that can be configured as needed by a particular application. The CDM Java Library does not have any restricted or protected methods by default - it is likely that each application based on the CDM will wish to protect services in a different way. The CDM service layer does provide a number of classes that make it straightforward to set up.

In addition to providing generic components for authentication and authorization, Spring Security provides a number of components that can be used by web applications. Details on authentication and authorization concepts applied to web applications can be found in the documentation for the cdmlib-remote package.

Identity

Identity in Spring Security is based around the UserDetails interface, that provides access to the principal's username, password, granted authorities and other details. The CDM provides the User class that implements this interface. In addition, it provides implementations of the GrantedAuthority and a Group class to allow group authorities (permissions that belong to a group of individuals rather than belonging to a single User). Creation of new user accounts, manipulation of account details, permissions, and group membership is achieved through an implementation of IUserService provided by the library.

The CDM provides some basic auditing functionality by storing the user account and timestamp each time an object is modified (and a transaction is comitted). The user details are retrieved from the SecurityContextHolder provided by Spring Security. If authentication is set up (see below) and the user is logged in, then this data will be present automatically in the SecurityContext. In the case of applications that do not use Spring Security, the User object must be placed into the SecurityContext explicitly for the user details to be recorded in this way.

Authentication

To enable authentication within your application, a small number of additional beans need to be added to the application context, thus (note the use of the security spring-security namespace):

<security:authentication-manager alias="authenticationManager"/>
   
<bean id="daoAuthenticationProvider" class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
  <security:custom-authentication-provider/>
  <property name="userDetailsService" ref="userService"/>
  <property name="saltSource" ref="saltSource"/>
  <property name="passwordEncoder" ref="passwordEncoder"/>
</bean>
    
<bean id="passwordEncoder" class="org.springframework.security.providers.encoding.Md5PasswordEncoder"/>
    
<bean id="saltSource" class="org.springframework.security.providers.dao.salt.ReflectionSaltSource">
  <property name="userPropertyToUse" value="getUsername"/>
</bean>

In the case of web applications, application developers will probably want to authenticate users transparently, using the servlet filter provided by spring security. For desktop applications, you can also authenticate a user programatically:

UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("username","password");
authenticationManager.authenticate(token);

Authorization

As with authentication, web applications based upon the CDM may find the standard methods provided by Spring Security or protecting URLs to be sufficient in most cases. To protect service methods, or to secure desktop applications, developers can also use global method security by specifying a pointcut expression that matches the service and method that they wish to protect, and a granted authority that is allowed to access the method thus:

<security:global-method-security>
  <security:protect-pointcut expression="execution(* eu.etaxonomy.cdm.api.service.UserService.changePasswordForUser(..))" access="ROLE_ADMINISTRATE"/>
</security:global-method-security>