Spring Security

Spring Security Annotation Based Hello World Example

In this tutorial of Spring Security Annotation Based Hello World Example, we will take a look into very simple hello world example of spring security annotation based in a Spring MVC environment. In previous tutorial We have seen same example in the Spring Security XML based in a Spring MVC. Here we going to show you how to create application in annotation or java config based spring security configuration.

Here I have used technologies as below :

  • Spring 4.3.5.RELEASE
  • Spring Security 4.2.1.RELEASE
  • STS 3.5.1
  • JDK 1.8
  • Maven 4
  • Tomcat 8 (Servlet 3.x)

 

In this tutorial I am using total java based configuration for web application as well so here I am using WebApplicationInitializer implementation to load the Spring Application Context file by Context Loader automatically. But this java configuration is required supported in Servlet 3.x container only i.e as of Tomcat 7 and as of Jetty 8.

Maven Dependency for this application

For this application we have following minimum maven dependencies. For Spring Security into web application we have required two jars only spring-security-web.jar and spring-security-context.jar.

<properties>
   <spring.version>4.3.5.RELEASE</spring.version>
   <spring.security.version>4.2.1.RELEASE</spring.security.version>
  </properties>
  
  <dependencies>
   <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-webmvc</artifactId>
     <version>${spring.version}</version>
 </dependency>
 
 <dependency>
     <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-config</artifactId>
     <version>${spring.security.version}</version>
 </dependency>
 
 <dependency>
     <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-web</artifactId>
     <version>${spring.security.version}</version>
 </dependency>
 
 <dependency>
     <groupId>jstl</groupId>
     <artifactId>jstl</artifactId>
     <version>1.2</version>
 </dependency>
  
  </dependencies>

Application Directory Structure

Here I have created web application using Maven as below directory structure for this application.

Spring Security Annotation or Java Configuration

Here we will see how to configure Spring Security in the Spring MVC application based annotation or java configuration. Follow my another tutorial of Spring Security Java based Annotation Configuration for more detail information about all Spring Security annotations and its used in the application.

Let’s create a Spring Security configuration file and annotated it with @EnableWebSecurity as below:

SecurityConfig.java

/**
 * 
 */
package com.doj.app.config.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

/**
 * @author Dinesh.Rajput
 *
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
 
 //Override Default configuration in WebSecurityConfigurerAdapter for custom login form and authorize requests
 //We specified multiple URL patterns that any user can access like "/login/".
 //Any URL that starts with "/admin/" will be restricted to users who have the role "ROLE_ADMIN". 
 //Any URL that has not already been matched on only requires that the user be authenticated
 @Override
 protected void configure(HttpSecurity http) throws Exception {
  http
   .authorizeRequests()                                                                
    .antMatchers("/resources/**", "/login").permitAll()                  
    .antMatchers("/admin/**").hasRole("ADMIN")                                      
    .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")            
    .anyRequest().authenticated()                                                   
    .and()
   .formLogin();
 }
 //In memory authentication java configuration
 //Not web-specific
 @Autowired
 public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
  auth
   .inMemoryAuthentication() //Adds a UserDetailsManagerConfigurer
    //login, password and supported role
    .withUser("user").password("password").roles("USER").and()
    .withUser("admin").password("dinesh").roles("ADMIN");
 }
}

In the previous example, its equivalent XML configuration file for Spring Security.
applicationContext-Security.xml

<?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:>
Here I have overridden configure(HttpSecurity http) method of WebSecurityConfigurerAdapter class of Spring Security for customization in authorization and authentication mechanism. By default this configure(HttpSecurity http) method of WebSecurityConfigurerAdapter apply the authentication to all application calls or URLs. But here URL like "/resources/**", "/login" permit for all without authentication required by using permitAll() method and URL like "/admin/**" is required a special ADMIN role for accessing it and else URLs of the web application is required authentication only for any ROLE either ADMIN, USER, DB etc..

Note: Access control for more specific URLs like "/admin/**", "/db/**" should be always define first above to the general case like "/**".

Note: As of Spring Security 4.0, @EnableWebMvcSecurity is deprecated. The replacement is @EnableWebSecurity which will determine adding the Spring MVC features based upon the classpath. To enable Spring Security integration with Spring MVC add the @EnableWebSecurity annotation to your configuration.

Loading Spring Security Filters Chain to Container

Spring Security has lot of filters to apply the security to the web application. But but we don't need to configure all filters in to web.xml or ApplicationInitializer class file of the application. Spring Security provides us a Special Filter bean class "SpringSecurityFilterChain" it is responsible for registering all filters into spring application context file as beans. And one more filter of Spring Security, "DelegatingFilterProxy" delegates the request to associated registered bean class into application context file with same name as filter name in the web.xml file. Let's see the below file that is responsible to loading Spring Security Context file to container. SecurityWebApplicationInitializer.java
/**
 * 
 */
package com.doj.app.web;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

/**
 * @author Dinesh.Rajput
 *
 */
public class SecurityWebApplicationInitializer extends
  AbstractSecurityWebApplicationInitializer {

}

This class SecurityWebApplicationInitializer.java does not have any body here but it extends AbstractSecurityWebApplicationInitializer, it will load the springSecurityFilterChain automatically define internally by Spring Security Framework. In previous XML based example it's equivalent XML configuration in the web.xml file as 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>

That is all about the Spring Security Annotation Based basic java configuration for this example. Let's see below file has Spring MVC configuration for this application.

WebMvcConfig.java

/**
 * 
 */
package com.doj.app.config.web;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

/**
 * @author Dinesh.Rajput
 *
 */
@Configuration
@EnableWebMvc
@ComponentScan("com.doj.app.web.controller")
public class WebMvcConfig {
 
 @Bean
 public ViewResolver viewResolver(){
  InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
  viewResolver.setPrefix("/WEB-INF/view/");
  viewResolver.setSuffix(".jsp");
  return viewResolver;
 }
}

It's equivalent configuration in the XML based configuration:

<context:component-scan base-package="com.doj.app.web.controller" />

<bean id="jspViewResolver"
 class="org.springframework.web.servlet.view.InternalResourceViewResolver">
 <property name="viewClass"
  value="org.springframework.web.servlet.view.JstlView" />
 <property name="prefix" value="/WEB-INF/view/" />
 <property name="suffix" value=".jsp" />
</bean>

Let's see WebApplicationInitializer class to load every thing to web container. This is file is equivalent to web.xml file in the XML based application.

ApplicationInitializer.java

/**
 * 
 */
package com.doj.app.web;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import com.doj.app.config.RootConfig;
import com.doj.app.config.security.SecurityConfig;
import com.doj.app.config.web.WebMvcConfig;

/**
 * @author Dinesh.Rajput
 *
 */
public class ApplicationInitializer extends
  AbstractAnnotationConfigDispatcherServletInitializer {

 @Override
 protected Class<?>[] getRootConfigClasses() {
  return new Class<?>[] { RootConfig.class, SecurityConfig.class };
 }

 @Override
 protected Class<?>[] getServletConfigClasses() {
  return new Class<?>[] { WebMvcConfig.class };
 }

 @Override
 protected String[] getServletMappings() {
  return new String[] {"/"};
 }

}

Finally we have a HomeController of application to handling requests from browser.

package com.doj.app.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author Dinesh Rajput
 *
 */
@Controller
public class HomeController {
 
 @GetMapping("/")
 public String home(ModelMap model) {
  model.addAttribute("message", "Learn Spring Security Hello World Example with Annotations");
  model.addAttribute("author", "User of Dinesh on Java");
  return "home";
 }
 
 @GetMapping("/admin/")
 public String admin(ModelMap model) {
  model.addAttribute("message", "Create Spring Security Hello World Example with Annotations");
  model.addAttribute("author", "Admin of Dinesh on Java");
  return "admin";
 }
}

Download Source Code of this Spring Security Annotation Example from Git.

Demo

Let's see demo of this example after successfully deployed to the tomcat 7 or 8.
After running server try to access the application then Spring Security will intercept the request and redirect to /login, and a default login form is displayed.

If username and password is incorrect or empty submit then it will display error messages, and Spring Security's ExceptionTranslationFilter will redirect to this URL /login?error.

If username and password is correct then it will redirect the request to the original requested URL and display the page.

Suppose we have logged in with "user" and "password" as configured above in the Spring Security Configuration, This user has Role "USER" and we are trying to access unauthorized resource of admin, required "ADMIN" role, Spring will display the 403 access denied page.

 

Previous
Next
Dinesh Rajput

Dinesh Rajput is the chief editor of a website Dineshonjava, a technical blog dedicated to the Spring and Java technologies. It has a series of articles related to Java technologies. Dinesh has been a Spring enthusiast since 2008 and is a Pivotal Certified Spring Professional, an author of a book Spring 5 Design Pattern, and a blogger. He has more than 10 years of experience with different aspects of Spring and Java design and development. His core expertise lies in the latest version of Spring Framework, Spring Boot, Spring Security, creating REST APIs, Microservice Architecture, Reactive Pattern, Spring AOP, Design Patterns, Struts, Hibernate, Web Services, Spring Batch, Cassandra, MongoDB, and Web Application Design and Architecture. He is currently working as a technology manager at a leading product and web development company. He worked as a developer and tech lead at the Bennett, Coleman & Co. Ltd and was the first developer in his previous company, Paytm. Dinesh is passionate about the latest Java technologies and loves to write technical blogs related to it. He is a very active member of the Java and Spring community on different forums. When it comes to the Spring Framework and Java, Dinesh tops the list!

Share
Published by
Dinesh Rajput

Recent Posts

Strategy Design Patterns using Lambda

Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…

2 years ago

Decorator Pattern using Lambda

Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…

2 years ago

Delegating pattern using lambda

Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…

2 years ago

Spring Vs Django- Know The Difference Between The Two

Technology has emerged a lot in the last decade, and now we have artificial intelligence;…

2 years ago

TOP 20 MongoDB INTERVIEW QUESTIONS 2022

Managing a database is becoming increasingly complex now due to the vast amount of data…

2 years ago

Scheduler @Scheduled Annotation Spring Boot

Overview In this article, we will explore Spring Scheduler how we could use it by…

3 years ago