Saturday, April 13, 2013

Spring security using a users database


I’ve started reading about spring, I know the general idea of how it works so I thought I should learn about spring security first. I’ve been reading the “spring security tutorial", which is pretty much straight forward, and there was an exercise of using a users database to authenticate the user. In this post I will be creating the users database and hooking it with spring security. 

I'll assume that you've got your environment all setup and good to go. What I will be using is:
I'll start by creating the "security" web project by importing the spring-security-samples-tutorial-X.war, where X is the version number of the spring security module you've downloaded. To do this, I've followed the following steps:

1. In spring toolkit, go to file-> import -> War file, then click on next
2. Select the spring-security-samples-tutorial-X.war file, name the web project as "security", target runtime environment "VMware vFabric..", then click on finish.
3. Go to the servers tab, right click on the default "VMware vFabric" development server and select "add and remove" option and add the security web application, then click on finish. After that right click on the server again and run the application.
You can now access the application through the url "http://localhost:8080/security".

How does it work?

If you have a look at the web.xml file, you will find a context param that is being used to set the location of the following files:

  • "applicationContext-business" file, which contains all the spring beans.
  • "applicationContext-security" file, which contains all the application security rules, such as which URLs are restricted to which roles or type of users(anonymous vs authenticated).
The file that I am interested in in this tutorial is the second one. If you have a look at that file, you'll find an "authentication-manager" tab, which lists all the users of the application under the "user-service" tag and which roles each user have. This is the part that needs to be changed to read from a database table instead of listing the users.

Doing a quick google search, I found this question on stackoverflow.com, which basically says that I'll have to create a bean which points to a class which extends AbstractUserDetailsAuthenticationProvider, then make my security provider reference this bean. Alas, things were not this simple, although not so complex, but needed a little bit of research. I'll list the steps I took to do this task instead of going the way I actually did:



  1. I've added the following libraries:
    Commons-dbcp-1.3.jar for BasicDatasource class
    Spring-tx-X for DataAccessException,UncategorizedDataAccessException
    commons-pool-1.6.jar for ObjectPool class
    ojdbc14.jar for the OracleDriver

    below is a snapshot of my lib folder for your reference.
  2. Used the following script to create a simple database structure for the users:
  3. Added records to sec_roles for "supervisor" and "user", created two users "scott" and "peter" and assigned the "supervisor" role to "scott" and the "user" role to "peter".
  4. Created a UserDao class to get the user information from the database:

    UserDao.java

  5. Created a custom authentication provider

    DBAuthenticationProvider.java



  6. Created a custom user details service

    UserDetailServiceImpl.java

  7. Added the beans to applicationContext-business.xml




  8. Modified the applicationContext-security.xml file to use the custom security provider and user details service:


A problem that I faced a lot was missing classes. You can refer back to the snapshot in point 1 to see what jars are included to solve your issues. After starting up the application successfully, you should be able to login as scott/scott for a user with supervisor role, and peter/peter for a normal user.

No comments:

Post a Comment