Quick Guide For Using Spring Roo and Spring Security In Rapid Web Application Development: 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 Contributor: Yassin Daanoun
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 1 project. 1.2 Spring Roo and Spring Framework Spring Roo 2 main 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 3 significantly reduces Enteprise Java code complexity by offering a development platform that uses interface-driven development, dependency injection, aspectoriented 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 4 provides 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 2 http://www.springsource.org/spring-roo 32 http://www.springsource.org/spring-roo 3 http://www.springsource.org/ 4 http://static.springsource.org/spring-security/site/
big community (also from the industry 5 ) is continousely contributing and improving this framework to 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/vmwareacquires-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> -->
<!-- <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> Configuration to enable HTTPS (keystore generation) 6 : <!-- Generating a SSL/TLS server key store --> <plugin> </plugin> <groupid>org.codehaus.mojo</groupid> <artifactid>keytool-maven-plugin</artifactid> <version>1.0</version> <executions> </executions> <execution> <phase>generate-resources</phase> <id>clean</id> <goals> </goals> </execution> <execution> <goal>clean</goal> <phase>generate-resources</phase> <id>genkey</id> <goals> </goals> </execution> <goal>genkey</goal> <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> Configuration to enable HTTPS on Jetty (keystore generation): <!-- Deploy on Jetty Server --> <plugin> <groupid>org.mortbay.jetty</groupid> <artifactid>maven-jetty-plugin</artifactid> 6 Some additional configuration tweaking for eclipse can be found in the appendix.
</plugin> <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> --> </connectors> </configuration> <connector implementation="org.mortbay.jetty.security.sslsocketconnector"> </connector> <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> 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-controllersapplicationcontext.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"> </bean> <property name="realmname" value="dime_realm" />
Adapted security configuration (spring security context file and web.xml file): <http create-session="ifrequired" auto-config="false" realm="dime_realm"> </http> <http-basic /> <intercept-url pattern="/**" access="role_owner" requires-channel="https" /> 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> <filter-name>springsecurityfilterchain</filter-name> <filter-class>org.springframework.web.filter.delegatingfilterproxy</filter-class>... <!-- <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" lowercasecomparisons="false"> </http> <http-basic /> <!-- HTTPS Testing --> <intercept-url pattern="/**" access="role_owner" requires-channel="https" /> <!-- HTTP Testing --> <!--<intercept-url pattern="/**" access="role_owner" /> --> <!-- Configure Authentication mechanism --> <authentication-manager alias="authenticationmanager"> <authentication-provider> <password-encoder ref="dimepasswordencoder">
<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 7 that 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> The generated classes and the access to them can then used to implement the access control to the functionalities and resources of the repsective web application. For instance, the roles and permissions could help in configuring the access to the business logic by using JSR-250 notations in code (@PreAuthorize annotation above method defines a default denyall rule for the methods in the class and override later with @PreAuthorize("hasRole('PERM_READ_FORUMS')")) with combination of the RBAC configuration implemented.
3 References Bourimi M., Scerri S., Planaguma M., Heupel M., Fatih, K., and Schwarte P. A two-level approach to ontology-based access control in pervasive personal servers. Scientific research paper (ger. Wissenschaftlicher Artikel), urn:nbn:de:hbz:467-5789 Mularien, P.,2010. Spring Security 3. Packt Publishing. 2010. Scerri S., Gimenez R., Herman F., Bourimi M., and Thiel S. digital.me towards an integrated Personal Information Sphere. Technical report, June 2011. Federated Social Web Summit, Berlin (Germany). June 3rd-5th 2011. Rimple, K., Penchikala, S. and Dickens, G. Spring Roo in Action. Manning Publications. 2012 (currently in press, accessed the MEAP program version) Walls, C. Spring in Action (Third Edition). Manning Publications. 2011. Wheeler, W., Wheeler, J. and White J. Spring in Practice. (1st edition). Manning Publications. 2012 (currently in press, accessed the MEAP program version)