Wednesday, August 13, 2014

Spring Security Introduction

Security is a moving target and requires a comprehensive solution to deal with it. Also security needs to be dealt at many layers. Security at operating system level and securing the traffic while in wire are some of them. As we are concerned with Application level security, we will look fundamentally into the way of security at application level.

Spring security (formerly known as acegi) has been a popular choice in Java based web applications. Spring security started as a small sideway project independent of mainline spring development. In 2007, it was formerly included into the main spring development and rechristened as Spring security.

Before we move further, let’s understand the concept of principal, authentication and authorization.

Principal represents the identity which can be a user or device or some other system.

Authentication is the process of establishing the identity, confirming that the Principal is actually the one what it claims to be.

Authorization is the process of establishing whether the principal is allowed to do certain things.
For example in web applications the Principal is represented by the username or login. For the authentication process to happen, the principal has to provide a password which establishes the claim of the Principal. Authorization will further decide what Principal can do with application. If Principal is an account holder in a bank, she will be allowed to access only her account details at banking site.

Spring security is built on top of spring framework and uses the concept of filters in Servlet engine. Filters are like servlet however they come into action before servlet and can decide whether the request needs to be forwarded to a servlet or not. Spring security registers filters with the application.

Let’s build a web application using spring security. You can use your favourite IDE for doing that. 

If you are using maven, then register the dependencies as
<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>org.springframework.security.core</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>org.springframework.security.config</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>org.springframework.security.web</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>       

If you need to use taglib, then add the taglib jar also.

<dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>org.springframework.security.taglibs</artifactId>
            <version>3.0.5.RELEASE</version>
        </dependency>

Now open the web.xml and copy the following lines:

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

<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>WEB-INF/spring-security.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>

<welcome-file-list>
   <welcome-file>index.jsp[/welcome-file>
</welcome-file-list>

The listener ContextLoaderListener is invoked by the web container whenever the application is loaded. This starts the Spring IOC container. Spring container reads the spring-security.xml (which we will write soon) to read the configuration details. Also a filter is registered, which url-pattern dictates that all the request to the container needs to be trapped by the filter. The filter in turn delegates the request details to the Spring managed beans. As an application developer we need not worry about that mechanism as it happens below the wraps. What we need to do is to write the spring-security.xml and place it in WEB-INF where we configure that how the authentication is going to happen. The minimal spring-secuirty.xml looks like

<beans xmlns="http://www.springframework.org/schema/beans"   
        security="http://www.springframework.org/schema/security"
        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.0.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">

<security:http auto-config='true'>
    <security:intercept-url pattern="/**" access="ROLE_USER" />
</security:http>

<security:authentication-provider>
    <security:user-service>
        <security:user name="abc" password="yyy"
            authorities="ROLE_USER, ROLE_ADMIN" />
        <security:user name="def" password="zzz"
                authorities="ROLE_USER" />
    </security:user-service>
</security:authentication-provider>

The http element plays a major role in enabling the authentication and authorization mechanism. If you come from older acegi school you will be surprised with the reduced amount of configuration. The spring security has adopted the default over configuration paradigm. The common settings are automatically configured which is dictated by attribute auto-config. The intercept-url pattern tells that all the request can only be accessed by ROLE_USER. Also we have give a list of user in authentication-provider element. This is similar to realm in conventional way of handling security. Here the user details including password is provided in this XML itself. However it’s not difficult to point it to a database or a LDAP server to retrieve the user data.

Write an index.jsp which is our welcome file and the starting point for application. Sample index.jsp:

Reached here

Now deploy the application in your web container and hit the application. A page asking for username and password will appear which will allow you to go further only if you give the username and password as in spring-security.xml. A remember me service is also automatically configured.

The default login page is automatically generated by the spring. If you want to put your customized login page you need to do the following in intercept-url element.

<security:http auto-config='true'>
   <security:intercept-url pattern="/login.jsp*" filters="none"/>
   <security:intercept-url pattern="/**" access="ROLE_USER" />
   <security:form-login login-page='/login.jsp'/>
</security:http>

Now the form-login mode will look for our login page. We have excluded login.jsp from intercept-url by using filters none. If we do not do this, we will not be able to even access our login.jsp page.

Once the user is authenticated, Spring security puts an Authentication object in the session of the User. When the next request comes from the same user, Spring checks that if in the seession the authentication object is residing. If authentication object is there, Spring allows the request to go further.

More Articles on Spring

No comments:

Post a Comment