Examples For Basic Access Control Mecahnisms Implmentation By Using
Spring Technologies
Keywords: Authentication; Authorisation; RBAC; Spring Roo; Spring Security;
Date:
07/12/2011
Author:
Mohamed Bourimi
1
Spring Technologies For Web Applications Rapid
Development of Secure Authentication and Authorisation
1.1
Introduction
The basic access control of any web application addresses at least the following points:
– Securing the communications layer used to acces the respective application.
– Securing the Web Layer and allowing for authentication mechanisms (ensuring the identity of
who is accessing the application).
– Allowing for authorization mechanisms to the application resources. A classical mechanism is
the usage of the Role Based Access Control (RBAC), which helps in assigning permissions to
roles coupled with the identity of the users (e.g., ROLE can be OWNER which has
persmission to do everything in the application. GUESTs might just be allowed to read forums
'PERM_READ_FORUMS' or something like this and so on).
– Securing Business Logic Access in terms of which methods could call a given functionality
within the application environment.
In the following, we want to introduce Spring Framework technologies that help in rapid web
application development. The following chapter will address concrete examples token from a
document describing the implementation of the access control engine of the digital.me
1project.
1.2
Spring Roo and Spring Framework
Spring Roo
2main goal is to ease Java-based development projects in terms of simplifying the
complexity of configuring an application architecture (especially those tasks taking place periodically
when creating an application from the scratch). Spring Roo can be seen as an powerfull extension
of the Spring Framework with this respect.
The Spring Framework
3significantly reduces Enteprise Java code complexity by offering a
development platform that uses interface-driven development, dependency injection,
aspect-oriented programming and a number of helper APIs and services. However, various configuration
as well as deployment tasks remain unsatisfacally addressed which is entended to be covered with
the help of Roo. For instance, Spring Roo includes plugins to manage Maven build files, configuring
security of the web application, adding messaging support and different persistence datasources
with just one line of commands! (Rimple et. al. 2012).
1.3
Spring Security Framework
Spring security
4provides a sophisticated authentication and access control system and became
widely adopted as the standard solution for securing Spring Framework based applications used in
critical applications (Walls, 2010). Spring Security 3 provides a bundle of resources that allow for
many common security practices to be declared or configured in a straightforward manner
(Mularien, 2010).
According to various technical literature, standards such as Java Authentication and Authorisation
Service (JAAS) or Java EE Security do offer some ways of performing some of the same
authentication and Authorisation functions, but the Spring Security module packages up
implementations in a concise way and offers powerful baseline configuration features available out
of the box, e.g., for various security topics such as authentication and Authorisation. Furthermore, a
1
http://www.dime-project.eu
2http://www.springsource.org/spring-roo
3http://www.springsource.org/
2http://www.springsource.org/spring-roo
3http://www.springsource.org/
4http://static.springsource.org/spring-security/site/cover new security topics and fix detected issues (Mularien, 2010).
Even though Spring Security's, application specific implementation concerns, architecture
limitations, and infrastructure integration requirements are likely to complicate implementations also
in the case of using Spring Security. However, Spring Security is a "hands-on" framework where
developer are able to customize or extend the code to fulfill requirements that go beyond the basic
out of the box options (Mularien, 2010).
5
Spring was recently aquired (for 420 million dollars,
http://www.readwriteweb.com/enterprise/2009/08/vmware-acquires-springsource-for-420-million.php) by VMware Inc., the leading company for virtualization technologies. With
this, the deployment of a Spring based PS into the cloud us assured since VMware is part of the Cloud Alliance targeting
inter-operability.
2
Examples For Basic Configuration and Functional
Documentation
2.1
Description
The following examples are taken from the work done in the context of the digital.me project (Scerri
et. all. 2011) with respect to the implementation of access control mechanisms of the first prototype
(Bourimi et. al. 2011).
Since Spring (Roo) and Spring Security are configuration based, we detail in the following the
needed configuration at the level of the hosting web container for deployment and operation as well
as the used classes.
2.2
Configuration for securing the communication and web layer
In order to secure the communication layer of any Web application, a SSL keystore is needed. For
that, the following maven support for generating SSL keystore and deployment on Tomcat and Jetty
can just be added to your pom.xml generated in your Roo project.
2.2.1 Enabling SSL Support
<!-- Deploy on Tomcat --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>tomcat-maven-plugin</artifactId> <version>1.1</version> <configuration> <url>http://${web.container.server}:${web.container.server.port}/manager/html</url> <warFile>target/dime-communications.war</warFile> <update>true</update> <username>${tomcat.user}</username> <password>${tomcat.password}</password> <httpsPort>${web.container.server.port}</httpsPort> <keystoreFile>${project.build.directory}/${key.store.filename}</keystoreFile> <keystorePass>${key.store.keypass}</keystorePass> <systemProperties> <org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH> true </org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH> </systemProperties> </configuration> </plugin><!-- Deploy on Jetty Server --> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>6.1.22</version> <configuration> <contextPath>dime-communications</contextPath> <scanIntervalSeconds>5</scanIntervalSeconds> <connectors> <!-- <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> --> <!-- <port>${web.container.server.port}</port> -->
<!-- </connector> --> <connector implementation="org.mortbay.jetty.security.SslSocketConnector"> <port>${web.container.server.port}</port> <maxIdleTime>60000</maxIdleTime> <keystore>${project.build.directory}/${key.store.filename}</keystore> <password>${key.store.keypass}</password> <keyPassword>${key.store.storepass}</keyPassword> </connector> </connectors> </configuration> </plugin>
Configuration to enable HTTPS (keystore generation)
6:
<!-- Generating a SSL/TLS server key store --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>keytool-maven-plugin</artifactId> <version>1.0</version> <executions> <execution> <phase>generate-resources</phase> <id>clean</id> <goals> <goal>clean</goal> </goals> </execution> <execution> <phase>generate-resources</phase> <id>genkey</id> <goals> <goal>genkey</goal> </goals> </execution> </executions> <configuration> <keystore>${project.build.directory}/${key.store.filename}</keystore>
<dname>cn=www.dime-project.eu, ou=None, L=Siegen, ST=None, o=USIEGEN, c=DE</dname> <keypass>${key.store.keypass}</keypass> <storepass>${key.store.storepass}</storepass> <alias>dime</alias> <keyalg>RSA</keyalg> </configuration> </plugin>
Configuration to enable HTTPS on Jetty (keystore generation):
<!-- Deploy on Jetty Server --> <plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.22</version> <configuration> <contextPath>dime-communications</contextPath> <scanIntervalSeconds>5</scanIntervalSeconds> <connectors> <!-- <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector"> --> <!-- <port>${web.container.server.port}</port> --> <!-- <maxIdleTime>60000</maxIdleTime> --> <!-- </connector> --> <connector implementation="org.mortbay.jetty.security.SslSocketConnector"> <port>${web.container.server.port}</port> <maxIdleTime>60000</maxIdleTime> <keystore>${project.build.directory}/${key.store.filename}</keystore> <password>${key.store.keypass}</password> <keyPassword>${key.store.storepass}</keyPassword> </connector> </connectors> </configuration> </plugin>
2.2.2 Configuration to enable Basic Authentication
Basic Authentication is a classical mean to ensure acces to web applications. An authentification
dialog is shown in the used web browser and asks for the user credentials (username and
password). In order to enable Basic Authentication support, the following steps have to be
performed. The first step is related to adding a separate spring security file to the global context of
the application and enabling there the Basic Authentication support:
<!-- ***************************************************** -->
<!-- ******* Load Application Context ******* -->
<!-- ***************************************************** --> <!-- <import resource="classpath*:META-INF/spring/spring/dime-controllers-applicationContext.xml" /> --> <import resource="classpath*:META-INF/spring/ps-applicationContext.xml" /> <import resource="classpath*:META-INF/spring/ps-applicationContext-security.xml" /> <!-- <import resource="classpath*:**/spring-config/datamining-context.xml" /> --> … <!-- ***************************************************** --> <!-- ******* Basic Authentication Services Layer ******* --> <!-- ***************************************************** -->
<bean id="basicAuthenticationFilter"
class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationEntryPoint" ref="authenticationEntryPoint" /> </bean>
<bean id="authenticationEntryPoint"
class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint"> <property name="realmName" value="dime_realm" />
<http create-session="ifRequired" auto-config="false" realm="dime_realm"> <http-basic />
<intercept-url pattern="/**" access="ROLE_OWNER" requires-channel="https" /> </http>
In order to enable Basic Authentication it is necessary to edit the web.xml in dime-communications
subproject and add the following:
<!-- Enables Spring Security --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> .... <!-- <filter-mapping> --> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2.2.3 Configruration to enable Hashing and Salting (spring security context file)
<?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://www.springframework.org/schema/security" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd"> <!-- HTTP(S) security configurations -->
<http create-session="ifRequired" auto-config="false" realm="dime_realm" lowercase-comparisons="false">
<http-basic />
<!-- HTTPS Testing -->
<intercept-url pattern="/**" access="ROLE_OWNER" requires-channel="https" />
<!-- HTTP Testing -->
<!--<intercept-url pattern="/**" access="ROLE_OWNER" /> --> </http>
<!-- Configure Authentication mechanism -->
<authentication-manager alias="authenticationManager"> <authentication-provider>
<salt-source ref="dimeSaltSource"/> </password-encoder>
<!-- Short-term implementation: Later with db support and runtime-adding of users and roles etc. -->
<!-- dimepass4owner and dimepass4guests --> <!-- </user-service> -->
<user-service id="userDetailsService" properties="/WEB-INF/ps-users.properties" />
</authentication-provider> </authentication-manager>
</beans:beans>
In the configuration shown above, the property file “ps-users.properties” contains the usernames
and their sha-256 hashed passwords.
2.3
Implementing RBAC with Roo and securing business logic access
In order to design a persistent solution for the following RBAC diagram concerned with the
management of user accounts at the server
-
side, the following Roo commands creates entities
7that
allow many users could have different roles and each role could have different permissions.
Permissions could be assigned to different roles at the same time and different roles could be
assigned to the same user at the same time, too.
entity --class ~.user.UserRole --testAutomatically
field string --fieldName roleName --notNull
entity --class ~.user.UserPermission --testAutomatically
field string --fieldName permissionName --unique --notNull
entity --class ~.user.UserAccount --testAutomatically
field string --fieldName userName --notNull
field string --fieldName password --notNull
field string --fieldName firstName --notNull
field string --fieldName lastName --notNull
field string --fieldName email --notNull
7
Please ensure that you configured well your persistense layer by using the Roo command „persistence setup“ and its
arguments (Persistence Provider like Hibernate, Database like MySQL, Database name etc.)
field string --fieldName enabled --sizeMax 1 --notNull
focus --class ~.user.UserPermission
field set --fieldName permissionRoles --type ~.user.UserRole --cardinality MANY_TO_MANY
focus --class ~.user.UserRole
field set --fieldName permissions --type ~.user.UserPermission --mappedBy permissionRoles
focus --class ~.user.UserRole
field set --fieldName roleAccounts --type ~.user.UserAccount --cardinality ONE_TO_MANY --mappedBy userRole
focus --class ~.user.UserAccount
field reference --fieldName userRole --type ~.user.UserRole --cardinality MANY_TO_ONE <connectors>