Saturday, March 27, 2010

Let us look at the Spring security filter chain

DelegatingFilterProxy

The DelegatingFilterProxy is a special filter provided by the Spring framework.It acts as a bridge connecting
the web container and spring application container. In other words it helps pipeline request processing
from the web container filter to a bean in Spring web application context.

DelegatingFilterProxy is configured in the web.xml as shown below:


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

DelegatingFilterProxy is essentially a dumb filter and implements no logic. Its sole responsibility is to delegate the Filter's methods through to a bean which is obtained from the Spring application context. This enables the bean to benefit from the Spring web application context lifecycle support and configuration flexibility.
This bean must implement javax.servlet.Filter and it must have the same name as that in the filter-name element.


FilterChainProxy

DelegatingFilterProxy is actually connected to a FilterChainProxy in the Spring application context.
The FilterChainProxy bean has the same name as the filter name in the web.xml
You all must be very bored hearing this again again. I am trying to get this deep into your head
as it is one area of common configuration mistake and subsequent head banging. Trivial errors are
always difficult to locate.

In our case the FilterChainProxy was configured by the namespace configuration. A typical FilterChainProxy
would look like this:

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
  <sec:filter-chain-map path-type="ant">
     <sec:filter-chain pattern="/SkyPhotoWeb/**" filters="
           securityContextPersistenceFilterWithASCFalse,
           basicAuthenticationFilter,
           exceptionTranslationFilter,
           filterSecurityInterceptor" />
     <sec:filter-chain pattern="/**" filters="
           securityContextPersistenceFilterWithASCTrue,
           formLoginFilter,
           exceptionTranslationFilter,
           filterSecurityInterceptor" />
  </sec:filter-chain-map>
</bean>


Now from the documentation -
"The namespace element filter-chain-map is used to set up the security filter chain(s) which are required within the application.
It maps a particular URL pattern to a chain of filters built up from the bean names specified in the filters element.
Both regular expressions and Ant Paths are supported, and the most specific URIs appear first.
At runtime the FilterChainProxy will locate the first URI pattern that matches the current web request and the list of filter beans specified
by the filters  attribute will be applied to that request.
The filters will be invoked in the order they are defined, so you have complete control over the filter chain which is applied to a particular URL."

As you may have already guessed the bean names in the filters atrribute is a comma separate list of
bean names configured in the Spring context. For the moment assume that they are there. I will come back to put them into action and lecture
more about them.

Now let us look into the lifecycle aspect of the FilterChainProxy.Today being a weekend, I am feeling a bit lazy so will
copy and paste again from the official documentation which gives very good information on the lifecycle aspects.

"In relation to lifecycle issues, the FilterChainProxy will always delegate init(FilterConfig) and destroy() 
methods through to the underlaying Filters if such methods are called against FilterChainProxy itself.
In this case, FilterChainProxy guarantees to only initialize and destroy each Filter bean once,
no matter how many times it is declared in the filter chain(s).
You control the overall choice as to whether these methods are called or not via the targetFilterLifecycle initialization parameter
of DelegatingFilterProxy.
By default this property is false and servlet container lifecycle invocations are not delegated through DelegatingFilterProxy."

Thats it for now. I know you guys are getting bored with theory. Please be patient, I will drop in few more theory session, and
soon get back to hands on stuff.
 

Monday, March 15, 2010

Pause - lets look inside Spring Security

So far we have been quick to setup Spring Security and apply it in our application. But behind that minimal configuration and non-invasive behavior lot has been happening behind the scenes.
It is time to uncover the activities under hood, draw some diagrams to understand the framework and move ahead in style. I will not draw out all the balls from the magic box now. Instead will slowly take out one ball at a time to make it slow and easy to comprehend and assimilate.

Let us go back to the web.xml configuration. You will see that we have configured a DelegatingFilterProxy. This filter is named 'springSecurityFilterChain'. The delegating filter proxy looks for a bean named 'springSecurityFilterChain' in the root Spring web application context. So note that this name is kind of a reserved bean name and should not be used elsewhere. The delegating filter proxy as the name suggests delegates the entire security processing then to the beans declared in the Spring web application context/ or security context. Now the question in your mind is that you never declared a bean with name - 'springSecurityFilterChain' , then from where on earth did the delegating filter proxy get it and the framework started running? Well the 'springSecurityFilterChain' bean is created by the declaration <http>....</http>

There is a lot to learn and understand with this namespace configuration - <http&gt. So it needs a be enjoyed slowly like a good whisky.

You must have already understood that Spring Security is based on servlet filters. This is what the official documentation says - "Spring Security's web infrastructure is based entirely on standard servlet filters. It doesn't use servlets or any other servlet-based frameworks (such as Spring MVC) internally, so it has no strong links to any particular web technology. It deals in HttpServletRequests and HttpServletResponses and doesn't care whether the requests come from a browser, a web service client, an HttpInvoker or an AJAX application. Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed from the configuration depending on which services are required. The ordering of the filters is important as there are dependencies between them. "

Just to extract the keywords - irrespective of the source of http request the intercepting filter (configured as a delegating filter proxy in web.xml) hands over the actual security processing to a filter chain configured internally or Spring web application context. The request passes through each of the internal filters and is processed depending on what are the security requirements of the application or what customization has been done. Note you can very well introduce your own filter.Also note that the order of the filter in the filter chain is very important and there may be dependencies between filters in the chain. A filter coming later in the chain may depend on some data produced by filter coming earlier in the chain. I will dig deep into all these and also take indepth look into different filters that are available out of the box and also try to show the use of a custom filter in the chain.

Since we used the new namespace based configuration, the required filters are automatically configured and no bean needs to be explicitly configured. But sometimes fine grained control is required (and these may not be supported in namespace based configuration). In this case it is very well possible to get full control over the filter chain and the filters.

Now I leave you with a big picture of Spring security. In my next post I will to uncover more details about Spring security and its filters. I will blow out that yellow box more in the next post.

Saturday, March 13, 2010

Adding anonymous or guest access in Spring Security

As you have seen in my previous post the access to index.html was restricted. Whenever the user tries to access this page they were redirected to the login page. But this should not be case. The logical index.html page should be accessible to guest users as well as authenticated users.
Turning this on is just a matter of configuration. This is shown in the modified spring-security.xml file.

Listing 1 - spring.security.xml

I have now added a new intercept url line.

<intercept-url pattern="/index.html" access="IS_AUTHENTICATED_ANONYMOUSLY" />

This line makes it possible to access index.html as a guest user. Now when you click on any link on the index.html page you will be redirected to the login page in case you have not signed in.

In my next post, I will try to get into some theoretical details/framework internals before
proceeding to the next round of coding and adding additional features.

Friday, March 12, 2010

Enabling Spring Security

1> Add few more jars in your WEB-INF/lib folder.
The current view of jars is shown in the figure below.
Figure 1 - Adding the Jars
2> Add a new member named - spring-security.xml in the WEB-INF/config folder. The contents of this file is shown in Listing 1 below:

Listing 1 - spring-security.xml
This is the bare minimum configuration you need to do to get Spring Security started. This is a great relief for those of you who had worked with earlier versions of Spring Security or its ancestor Acegi Security. You had to explicitly configure the entire filter chain. That was tedious and very cumbersome leading to lot of errors and time and effort going down the drain. Thanks Ben and team for this good change. I will explain the different elements in this configuration in future posts as the intention of this post is to quickly get started with Spring Security as promised earlier.

Step 3 - wire everything now in the web.xml. The modified web.xml looks like the one shown below.
There are a few things to note here.
  • We have setup DelegatingFilterProxy which will look for a bean springSecurityFilterChain in the spring root web application context.
  • The springSecurityFilterChain bean is setup automatically by the tag.
  • The DispatcherServlet only has a specific web application context and hence you need to load the root web application context using the ContextLoaderListener. For now this listener only loads the security related beans in the root web application context.
  • The ContextLoaderListener must be configured after the log4j listener if the later is used.
  • If you do not use the ContextLoaderListener you will encounter the following exception
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?

Now that we are all set its time for testing. So launch your favorite browser (mine is Mozilla Firefox) and type the following:
http://localhost:8080/SkyPhotoWeb/index.html

** By the way I am deploying on Tomcat 6 running on JRE 6.

You will be redirected to a login page shown in figure below.



This is a Spring security framework generated login page. Although the desired result is not what we intended (we donot want that the index page is accessed securily rather by all users and guests) but it is clear that Spring Security is up and running, integrated into our Spring MVC application. I will try to correct this in my future post.Also I will show how you how you can add a custom your application specific login page.

Now let us supply the user id and password (jimi/jimispassword) and see what happens. You will be redirected to the index.html page. So it also suggests that Spring Security remembers what you tried prior to signing in.

Thats all for today hopefully. If I find time between watching Indial Premier League and World Field Hockey Finals I will try to clarify a few concepts later in the day.

Getting the security less application ready

1> Add jstl.jar (version 1.1 i guess) to your WEB-INF/lib folder
2> Modify index.jsp as shown below
Listing 1 - index.jsp 3> Add a controller for the landing or index page.
Listing 2 - EntryController.java 4> Add a controller for the upload page view
Listing 3 - UploadController.java 5> Time to launch the browser and test it on the browser.
Figure 1 - Skyphotos

6> Click on upload photo, you will see it is accessible to any one. But only logged on users should be able to access that page.

Figure 2 - secure page

In the next post I will start with the first step to ensure that a user is logged in / signed in before he or she can access the upload photo page.

Thursday, March 11, 2010

Adding few more JSPs and Security Requirements

Now I will add two more JSPs – one is the home page showing some dashboard information and the other is the file upload JSP which will be used to upload photos.

Listing 1 – home.jsp
Listing 2 – upload.jsp
Requirement
  1. index.jsp should be accessible without any security filtering
  2. home.jsp should be accessible only to registered users
  3. upload.jsp should only be accessible to registered users
Since the JSPs are placed under WEB-INF in any case no one can directly access it. So in the next post I will try to add a few page controllers to the scheme of things to make these pages accessible without any application security credentials.

Setting up Spring MVC 3 Web Application

Now its time to code a bit in Skyphoto. So launch Eclipe and create a dynamic web project ready to be deployed on Tomcat 6. I am assuming that readers are atleast familiar with this. Next we will do a bit of configuration and throw in some Spring 3 jar files into the WEB-INF/lib folder.
Step 1 - Configure Spring Servlets and log4j in the web application deployment descriptor.

Step 2 - log4j.xml
The log4j configuration will be very useful later to see all framework and application messages. I have set it to debug level to help understand the framework better.
Step 3 - Setting up a bare minimal spring configuration file Listing 3 - spring-web.xml
Step 4 - setup a simple jsp Listing 4 - index.jsp
Figure 1 - Project Directory Structure in Eclipse
Finally here is a view of the Eclipse project shown in Figure 1. You can very well make out the jar files you need for the time being.

  • Note 1 - that I am storing all configuration files under /WEB-INF/config
  • Note 2 - donot forget to download Spring framework and Security security distributions from their respective websites.

Exploring Spring Security 3

I am finally back to writing again after an absence of almost year and half. I will try to be more regular from now now. In this edition I will start with Spring Security 3. This will be a series of posts where I will try to build a very simple photo uploading and sharing service. This is actually my PoC with Spring Security 3.

Spring Security unlike most Spring product portfolio is a not at all well documented. The tutorials available on googling are mostly outdated. Spring Security 3 certainly by look of things seems to be a very good feature rich product yet hefty beast. So here is my attempt to conquer it.




Skyphoto Basic Requirements

  1. Securely upload photos into your account
  2. Download photos
  3. Share photos with friends and other application



In the course of this simple application development I will try to uncover most of the features of Spring Security. I will use Restful services support provided by Spring MVC so that I can expose a simple API for external applications which will consume the services of Skyphoto.