Spring Security – Basic authentication (xml)

Spring Security is a framework that focuses on providing both authentication and authorization to Java EE-based enterprise software applications. We will be securing the following application with spring security.

spring-security-xml1

Its a simple spring 4 mvc application made using spring tiles. To know more how this was made, please go through my spring-tiles tutorials. As you can see it has a simple home page with a couple of links on top right. Right now every one can access all of these links. I will be applying spring security via xml and build on this previous application. Lets start by adding the spring security dependencies in pom.xml:


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mynotes</groupId>
<artifactId>spring-security-xml</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>

<properties>
<springframework-version>4.3.2.RELEASE</springframework-version>
<springsecurity-version>4.1.3.RELEASE</springsecurity-version>
<tiles-version>3.0.5</tiles-version>
</properties>
<dependencies>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework-version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework-version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${springsecurity-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${springsecurity-version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>${tiles-version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>${tiles-version}</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>${tiles-version}</version>
</dependency>

<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>${tiles-version}</version>
</dependency>

</dependencies>
<build>
<finalName>spring-tiles</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<!-- <configuration> <path>/</path> <port>8899</port> </configuration> -->
</plugin>
</plugins>
</build>
</project>

Notice the springsecurity-version. We will be using 4.1.3. The next we will be changing the web.xml file:


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>spring-security-xml</display-name>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

<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>
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
</param-value>
</context-param>
</web-app>

Notice the springSecurityFilterChain filter. Make sure this filter has exactly this name. Its a bean internal to spring security. The filter class is going to be DelegatingFilterProxy. We then map all the request through this bean using the filter-mapping. We will be keeping spring configuration into a different file using the contextConfiguration giving the spring-security.xml path. Lets write in this file.


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

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

<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="password" authorities="ROLE_USER"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>

</beans>

First we added spring security related tags. Now we can access using security tag. The first tag we want is the http tag. The first attribute is the auto-config. Norrmally its not equal true, but for now, to learn the basics lets keep this to true. This will tell spring security to put in number of defaults in place. The next this we will set is use-expressions. Lets for now keep it to false. Now within the http tag, we can set intercept-url, where we can say, we want to protect some resources. This is done by the patter attribute. This pattern will be check for every incoming request. Here we are using an ant style pattern “/**“, meaning every resources of our application will be protected. Now will give the access attribute, which tells spring what sort of role or authority do you need to have in order to access these resources. Here we have specify ROLE_USER. Till now we were dealing with authorization, meaning what type of user has access to which type of resources.
Now lets create authentication. For that we add authentication-manager tag. Within this we set up authentication-provider. For now lets hardcode a user and a role. Lets restart our service – mvn tomcat7:run

spring-security-xml2

We are now presented with this login form. This form is of spring, its because of the auto-config of spring, which we set to true. Put on the credential to see the home page.

So till now all our resources are protected, and in order to see these we must have a valid credential with appropriate role. This is now a common scenario, we dont have to login to a website to view the home page. We will be applying some configuration that allow us to customise, which resources could be access by which principles.  Changing spring-security.xml.


<security:http auto-config="true" use-expressions="false">
<security:intercept-url pattern="/products" access="ROLE_USER"/>
<security:intercept-url pattern="/admin" access="ROLE_SITE_ADMIN"/>
<security:intercept-url pattern="/**" access="ROLE_ANONYMOUS,ROLE_USER,ROLE_SITE_ADMIN"/>
</security:http>

<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="password" authorities="ROLE_USER"/>
<security:user name="admin" password="password" authorities="ROLE_USER,ROLE_SITE_ADMIN"/>
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>

Now we added another user with role SITE_ADMIN and USER. These authorities could be anything you want. the the http we added a couple of intercept urls. We have  ‘/products’ url access to ROLE_USER and ‘/admin’ url access to both ROLE_USER and ROLE_SITE_ADMIN. Rest all urls ‘/**’ is accessible to both these users and ROLE_ANONYMOUS. <strong>Anonymous role is a default to spring. This says allow people those who are not authenticated to haves access. access = “ROLE_ANONYMOUS” allows access for non-authenticated users, but denies for the authenticated ones. Thats why we added other authorities to it.</strong>
Note that <strong>the order in which the intercept url is written is very important</strong>. If the ROLE_ANONYMOUS is written first, all the urls will be accessible to everyone as<strong> spring check for the access in the order which they are written.</strong>

Till now our <strong>authentication is done by a form that is generated by the spring framework</strong>. We are going to change that to http basic authentication. So <strong>instead of spring security generating a form, we are going to use the browsers underlying security mechanism</strong> that is built into http. Changing spring-security.xml:


<security:http auto-config="true" use-expressions="false">
<security:http-basic/>
<security:intercept-url pattern="/products" access="ROLE_USER"/>
<security:intercept-url pattern="/admin" access="ROLE_SITE_ADMIN"/>
<security:intercept-url pattern="/**" access="ROLE_ANONYMOUS,ROLE_USER,ROLE_SITE_ADMIN"/>
</security:http>

Notice the <security:http-basic/> tag. Lets run now:

spring-security-xml3

So we are getting a form for authentication that is native to the chrome browser.

Thats it for now, next we will see more into spring security. You can grab the code from my github repo.

Advertisements
%d bloggers like this: