7. Hello Spring Security

This section covers a minimal Spring Security application that uses Spring Boot, Java Configuration, or XML Configuration.

7.1 Hello Spring Security (Boot)

This section covers the minimum setup for how to use Spring Security with Spring Boot. For how to use Spring Security with Java Configuration, see Section 7.2, “Hello Spring Security (Java Configuration)”. For how to use Spring Security with XML Configuration, see Section 7.3, “Hello Spring Security (XML)”.

[Note]Note

The completed application can be found at samples/boot/helloworld

7.1.1 Updating Dependencies

The only step you need to do is update the dependencies by using Maven or Gradle. For your convenience, you can download a minimal Spring Boot + Spring Security application by clicking here.

7.1.2 Starting Hello Spring Security Boot

You can now run the Spring Boot application by using the Maven Plugin’s run goal. The following example shows how to do so (and the beginning of the output from doing so):

Example 7.1. Running Spring Boot Application

$ ./mvn spring-boot:run
...
INFO 23689 --- [  restartedMain] .s.s.UserDetailsServiceAutoConfiguration :

Using generated security password: 8e557245-73e2-4286-969a-ff57fe326336

...

7.1.3 Spring Boot Auto Configuration

Spring Boot automatically:

  • Enables Spring Security’s default configuration, which creates a servlet Filter as a bean named springSecurityFilterChain. This bean is responsible for all the security (protecting the application URLs, validating submitted username and passwords, redirecting to the log in form, and so on) within your application.
  • Creates a UserDetailsService bean with a username of user and a randomly generated password that is logged to the console.
  • Registers the Filter with a bean named springSecurityFilterChain with the Servlet container for every request.

Spring Boot is not configuring much, but it does a lot. A summary of the features follows:

7.2 Hello Spring Security (Java Configuration)

This section covers how to use Spring Security with Java Configuration. For how to use Spring Security with XML configuration, see Section 7.3, “Hello Spring Security (XML)”. For how to use Spring Security with Spring Boot configuration, see Section 7.1, “Hello Spring Security (Boot)”.

[Note]Note

You can find the completed application at samples/javaconfig/helloworld.

7.2.1 Updating Dependencies

The first step is to update the dependencies by using Maven or Gradle.

7.2.2 Minimal @EnableWebSecurity Configuration

The first step is to create our Spring Security Java configuration. The configuration creates a servlet Filter (known as the springSecurityFilterChain), which is responsible for all the security features (protecting the application URLs, validating submitted username and passwords, redirecting to the log in form, and so on) within your application. The following example shows the most basic example of a Spring Security Java Configuration:

Example 7.2. WebSecurity.java

import org.springframework.context.annotation.*;
import org.springframework.security.config.annotation.web.configuration.*;
import org.springframework.security.core.userdetails.*;
import org.springframework.security.provisioning.*;

@EnableWebSecurity
public class WebSecurityConfig {

    // @formatter:off
    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        return  new InMemoryUserDetailsManager(user);
    }
    // @formatter:on
}

There really is not much to this configuration, but it does a lot. A summary of the features follows:

7.2.3 Using AbstractSecurityWebApplicationInitializer

The next step is to register the springSecurityFilterChain with the war. Spring Security provides a base class (AbstractSecurityWebApplicationInitializer) that leverages Spring’s WebApplicationInitializer support.

The following example shows an example configuration:

Example 7.3. SecurityInitializer.java

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

public class SecurityInitializer
    extends AbstractSecurityWebApplicationInitializer {

    public SecurityInitializer() {
        super(WebSecurityConfig.class);
    }
}

The SecurityInitializer does the following things:

  • Adds a ContextLoaderListener that loads the WebSecurityConfig.
  • Finds the bean of type Filter named springSecurityFilterChain and registers it to process every URL in the application.
[Note]Note

If you are integrating with a Spring MVC application, be sure to configure the DispatcherServlet to load the configuration from the root ApplicationContext. The following example shows how to do so:

Example 7.4. MvcInitializer.java

public class MvcInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    // the Root Config is registered in SecurityInitializer
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    // the Spring MVC configuration should be added to SecurityInitializer constructor
    // i.e.
    // super(MvcConfig.class, WebSecurityConfig.class);
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

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

}

7.3 Hello Spring Security (XML)

This section covers how to use Spring Security with XML Configuration. For how to use Spring Security with Java configuration, see Section 7.2, “Hello Spring Security (Java Configuration)”. For how to use Spring Security with Spring Boot configuration, see Section 7.1, “Hello Spring Security (Boot)”.

7.3.1 Updating Dependencies

The first step is to update the dependencies by using Maven or Gradle.

7.3.2 Minimal <http> Configuration

In this section, we discuss how to use Spring Security with XML Configuration.

[Note]Note

The completed application can be found at samples/xml/helloworld

The first step is to create our Spring Security XML Configuration. The configuration creates a Servlet Filter (known as the springSecurityFilterChain), which is responsible for all the security (protecting the application URLs, validating submitted username and passwords, redirecting to the log in form, and so on) within your application. The following example shows the most basic example of a Spring Security XML Configuration:

Example 7.5. src/main/webapp/WEB-INF/spring/security.xml

<b:beans xmlns="http://www.springframework.org/schema/security"
         xmlns:b="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/security https://www.springframework.org/schema/security/spring-security.xsd">
    <http />

    <user-service>
        <user name="user" password="{noop}password" authorities="ROLE_USER" />
    </user-service>
</b:beans>

There really is not much to this configuration, but it does a lot. A summary of the features follows:

7.3.3 web.xml Configuration

The next step is to ensure that our Security configuration is being read in. To do so, we need to ensure a ContextLoaderListener is registered and the contextConfigLocation is including the configuration. The following example shows how to do so:

Example 7.6. src/main/webapp/WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <!--
        Loads the Spring configurations from contextConfigLocation
    -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--
        The locations of the Spring Configuration. In this case, all configuration is
        in /WEB-INF/spring/
    -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/*.xml
        </param-value>
    </context-param>

    <!--
        DelegatingFilterProxy looks for a Spring bean by the name of filter (springSecurityFilterChain) and delegates
        all work to that Bean. This is how the Servlet Container can a Spring Bean to act as a Servlet Filter.
    -->
    <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>

</web-app>

[Note]Note

If you integrate with an existing Spring MVC application, be sure to configure the DispatcherServlet to load the configuration from the root ApplicationContext. The following example shows how to do so:

src/main/webapp/WEB-INF/web.xml. 

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- Load Spring MVC configuration from root ApplicationContext (context-param from above) -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
</servlet>

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