25 Aug 2012

Spring Security 3 with RESTful Authentication

Over the last few weeks I have been creating a RESTful API for a new product I have been working on. I decided to go with Spring MVC with Jackson JSON handling the output and securing it all with Spring Security 3. Below is a quick tutorial on how to setup Spring Security.

A complete demo web app can be found at github. This was tested and working in tomcat 7.0.28 however it should be agnostic to all versions and containers (note, that the only user configured in the demo app is username=jack password=jill).

Creating the filter in your web.xml

The XML below shows the insertion of the filter springSecurityFilterChain of type DelegatingFilterProxy. Ensure you don't change the name from "springSecurityFilterChain", this is important as later on we will be using the <http> namespace which automatically creates a bean with this name. The DelegatingFilterProxy filter is a simple class that will attempt to delegate the request to a spring bean with the same as that of the filter-name (i.e. springSecurityFilterChain).


Application Context Setup

The application context XML (shown below) sets up the basic Filter Chain with the inclusion of a custom filter provided by us. There is also a few dot points outlining the functionality of each of the namespaces and beans.


  • The <http> namespace creates a filter chain with a bean name springSecurityFilterChain
    • Within this chain there are essential Spring Security filters that must be present.
    • The <custom-filter> allows us to inject our own security filter into the springSecurityFilterChain. Our customer filter will be called by the springSecurityFilterChain when a request enters
    • The position attribute in the <custom-filter> namespace tells Spring Security where to place our filter in the chain (have a look at the Filter Ordering for more detail)
    • The <intercept-url> namespace allows us to tell Spring Security which URLs this filter chain should handle and the access level required to access this URL.
    • Since this is a RESTful service we ensure that sessions are not created when a request is made by use of the create-session="stateless".
  • The customRestFilter is the class that will be passed the request and response object. It is responsible for retrieving and manipulating any request data to pass to the authentication provider to authenticate.
  • The restAuthenticationProvider is the class responsible for verifying that the username and password are valid and returning an AuthenticationToken matching the user requesting the resource and the user's access level. This is the place where you would normally hook into a more complex authentication system and user data layer.
  • The <authentication-manager> namespace allows us to wrap multiple providers into an AuthenticationManager that will select the appropriate provider based on the request.
  • The authenticationEntryPoint allows us to customise to start the authentication process or launch when authentication fails. For this demonstation the BasicAuthenticationEntryPoint prompts the user for a username and password when no Authorization Header is found or if an incorrect username or password is entered. You may notice that the <http> namespace also takes an entry-point-ref. The exceptionTranslationFilter that is created as part of the springSecurityFilterChain will use this entry point class to begin the authentication process or decide on an action if it fails (e.g. when using the HTTP403ForbiddenEntryPoint).
And that is pretty much it. Check out the demo project in github, it has a lot more comments describing the functionality and possible extension points for your application. The Spring Security Documentation is also really comprehensive so if you are stuck make sure you read it.

The main reason why I wrote this post was that when searching for some examples on Spring Security and REST, all the examples found were extending the AbstractAuthenticationProcessingFilter class. The class is designed with the ability to create sessions, provide redirects and other tools that are made use of with more traditional security methods with login pages. My design was based on Spring's BasicAuthenticationFilter class that simply extends the GenericFilterBean. This proved to be a much simpler task. 

8 comments:

  1. Great,
    really interesting article.

    ReplyDelete
  2. test it with:

    curl -i --user jack:jill -H "Content-Type: application/json" -H "Accept: application/json" -X GET http://localhost:8080/restful/rest/api/json/1

    This means there is a basic authentication for each post.

    ReplyDelete
  3. Thank man! very concise and clear.

    ReplyDelete
  4. I'm sorry, I have a problem with the SimpleGrantedAuthority lib. Can you help me please?

    ReplyDelete
  5. Thanks for this simple but very helpful post!

    ReplyDelete
  6. Very useful post!
    Just curious why didn't you use BasicAuthenticationFilter?

    ReplyDelete
  7. Hi,
    How can i do the same thing with annotations configuration ?

    ReplyDelete