Parancoe Security

In this tutorial I’ll show you how to configure your parancoe web application in order to secure it.

Introduction

Security in parancoe has been implemented using Acegi framework. Acegi Security is sub-project of spring framework, it provides security services for J2EE software applications, especially if they are built using Spring. We chose to implement security in parancoe using the plugin way, so you are free to use the security parancoe features in your parancoe web application and, above all, you have NOT to define the filter used by acegi in the web.xml because it uses an Handlerinterceptor to call the chains of filters.

The security plugin manages security aspects restricted to authentication and authorization processes. The default configuration of the plugin provides:

  • Form-based authentication
  • Authorization based on protected url associated to roles

If the user asks for a protected resources the plugin intercepts the request, verify if the user is authenticated and if he is not forwards him to the login page (provided by the archetype). If the user is authenticated but he is not in any of the roles associated to the protected resourse he will be redirected to the accessDeniedpage (still provided by the archetype).

Standard Configuration

In order to use the security plugin you have to declare it as dependency in your pom.xml application file, that is the pom file that the parancoe web archetype creates for you.

    <dependency>
            <groupId>org.parancoe</groupId>
            <artifactId>parancoe-plugin-security</artifactId>
            <version>0.3.2</version>
            <scope>compile</scope>
    </dependency>
Refer to the last version relased of the security plugin. In order to associate the protected url (resources) to the roles you define in you web application you have to edit the parancoe-servlet.xml file and add the pluginSecurityFilterDefinitions definition. Here the configuration used for jugevents application.

<bean name="pluginSecurityFilterDefinitions" 
 class="java.lang.String">
        <constructor-arg>
            <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /adminjugger/**=ROLE_ADMIN
                /people/**=ROLE_ADMIN, ROLE_PARANCOE
                /event/edit*=ROLE_ADMIN, ROLE_JUGGER
                /event/delete*=ROLE_ADMIN, ROLE_JUGGER
                /event/participants*=ROLE_ADMIN, ROLE_JUGGER
                /admin/**=ROLE_ADMIN
                /**=IS_AUTHENTICATED_ANONYMOUSLY
            </value>
        </constructor-arg>
    </bean>
The informations concerning users, roles are stored in three tables of the database which the plugin creates automatically for you.
  • PSEC_USER: informations about username, password, enabled;
  • AUTHORITY: defines all the roles of your application;
  • USER_AUTHORITY: represents the relation between users and roles.

You have to fill with the users and the roles that you’ll use in the application. At this point you are done, we have only edited the pom.xml and the parancoe-servlet.xml file and now we have a secure web application. It’s easy, it’s the parancoe way.

Configuration for existing database

If you need to retrieve informations about security from an existing database and you don’t want to create the tables described above you have to edit the parancoe-servlet.xml and add the userDetailsService configuration. Here the configuration used in the plugin.

<bean id="userDetailsService" class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
        <property name="usersByUsernameQuery">
            <value>select username, password, enabled FROM psec_user WHERE username = ?</value>
        </property>
        <property name="authoritiesByUsernameQuery">
            <value>select username, role from psec_user u, authority a, user_authority ua 
            where u.username = ? and u.id = ua.user_id and a.id = ua.authority_id</value>
        </property>
    </bean>      
You have to replace the usersByUsernameQuery and authoritiesByUsernameQuery queries with your database specific queries.

Presentation

The plugin uses the acegi tag library to implement dynamic menu based on the user logged. Please refer to the acegi documentation to understand how to use use them.

...to be continued.

Posted by Enrico Giurin on Monday, October 01, 2007