Showing posts with label security. Show all posts
Showing posts with label security. Show all posts

Monday, June 1, 2009

Spring Security for Orbeon

My main Orbeon application was using the Tomcat Realm security mechanism which turned out to be fairly easy to use and setup. I even wrote a simple Java class to authenticate users against an eXist (XMLDB) database. But I needed more flexibility and robustness and my colleague Pedro suggested I should use the Spring Security framework (aka ACEGI security). I had worked with ACEGI security in previous projects and knew how powerful and flexible it was but from what I could recall, it's configuration and use was not trivial. Well, that has changed quite a bit with the new 2.x version, now an official component of the Spring framework and called "Spring Security".

In fact, I can say that it took me less than half a day to get everything up and running with authentication for my Orbeon-based web app being done against an SQL database. Now, I just have to setup my access policies and roles to exploit the power and flexibility of this framework. I also have the flexibility to eventually add password encryption, LDAP authentication, ACLs etc.

On the more practical aspects, here is a simple rundown on what needs to be done.
First, I was hoping I could use only a small subset of the Spring jars but at the finish line, you need most of the jars that come with Spring. Here is the list of jars I finally ended up with:
  • spring-security-core-2.*.jar
  • org.springframework.aop-3.*.jar
  • org.springframework.beans-3.*.jar
  • org.springframework.context-3.*.jar
  • org.springframework.core-3.*.jar
  • org.springframework.expression-3.*.jar
  • org.springframework.jdbc-3.*.jar
  • org.springframework.transaction-3.*.jar
  • org.springframework.web-3.*.jar
  • com.springsource.org.antlr-3.0.1.jar
  • commons-logging-1.0.4.jar
Here are the elements I added to my web.xml file:

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-security-context.xml</param-value>
</context-param>

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

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

The content of my spring-security-context.xml file is:
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">

<http auto-config='true'>
<intercept-url pattern="/auth/login*" filters="none" />
<intercept-url pattern="/wfdemo/**" access="ROLE_USER" />
<form-login login-page="/auth/login" />
</http>

<authentication-provider user-service-ref='userDetailsService'/>

<beans:bean id="authDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
<beans:property name="url"
value="jdbc:mysql://localhost:3306/***" />
<beans:property name="username" value="???" />
<beans:property name="password" value="****" />
</beans:bean>

<beans:bean id="userDetailsService"
class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
<beans:property name="dataSource" ref="authDataSource" />
</beans:bean>
</beans:beans>
As for the login form, I just had to change the action attribute value to "j_spring_security_check" as such:
<form action="/j_spring_security_check" method="post">
I obviously had to create a database and tables used by the userDetailsService. The Spring documentation contains details on the DDL.

Et voila! I have form-based authentication for my Orbeon application using JDBC and Spring Security configured with a Spring application context.

That's pretty much all there is to it folks.

Have fun with Orbeon and Spring!