This guide provides instructions on how to add Spring Security to an existing application using XML configuration.

Setting up the sample

This section outlines how to setup a workspace within Eclipse IDE with Spring Tools so that you can follow along with this guide. The next section outlines generic steps for how to apply Spring Security to your existing application. While you could simply apply the steps to your existing application, we encourage you to follow along with this guide in order to reduce the complexity.

Obtaining the sample project

Clone the Spring Security Samples project to a known location and remember it as SPRING_SECURITY_HOME.

These samples are being migrated to a separate project, however, you can still find the not migrated samples in an older branch of the Spring Security repository.

Import the insecure sample application

In order to follow along, we encourage you to import the insecure sample application into your IDE. You may use any IDE you prefer, but the instructions in this guide will assume you are using Spring Tool Suite (STS).

The completed sample application can be found at SPRING_SECURITY_HOME/samples/xml/helloworld
  • If you do not have STS installed, download STS from https://spring.io/tools

  • Start STS and import the sample application into STS using the following steps:

    • File→Import

    • Existing Maven Projects

    • Click Next >

    • Click Browse…​

    • Navigate to the samples (i.e. SPRING_SECURITY_HOME/samples/xml/insecure) and click OK

    • Click Finish

Running the insecure application

In the following exercise we will be modifying the spring-security-samples-xml-insecure application. Before we make any changes, it is best to verify that the sample works properly. Perform the following steps to ensure that spring-security-samples-xml-insecure works.

  • Right click on the spring-security-samples-xml-insecure application

  • Select Run As→Run on Server

  • Select the latest tc Server

  • Click Finish

Verify the application is working by ensuring a page stating TODO Secure this is displayed at http://localhost:8080/sample/

Once you have verified the application runs, stop the application server using the following steps:

  • In the Servers view select the latest tc Server

  • Click the stop button (a red square) to stop the application server

Securing the application

Before securing your application, it is important to ensure that the existing application works as we did in Running the insecure application. Now that the application runs without security, we are ready to add security to our application. This section demonstrates the minimal steps to add Spring Security to our application.

Updating your dependencies

In order to resolve Spring Security milestones and release candidates add the Spring Milestone repository. For our example, the repository has already been added for you. In the event you were working on another application, you would need to ensure you add the following to your pom:

pom.xml
<repositories>
  <!-- ... possibly other repository elements ... -->
  <repository>
    <id>spring-milestone</id>
    <name>Spring Milestone Repository</name>
    <url>https://repo.spring.io/milestone</url>
  </repository>
</repositories>

In order to use Spring Security you must add the necessary dependencies. For the sample we will add the following Spring Security dependencies:

pom.xml
<dependencies>
  <!-- ... other dependency elements ... -->
  <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>5.5.3</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>5.5.3</version>
  </dependency>
</dependencies>

After you have completed this, you need to ensure that STS knows about the updated dependencies by:

  • Right click on the spring-security-samples-xml-insecure application

  • Select Maven→Update project…​

  • Ensure the project is selected, and click OK

Creating your Spring Security configuration

The next step is to create a Spring Security configuration.

  • In the Package Explorer view, right click on the folder src/main/webapp

  • Select New→Folder

  • Enter WEB-INF/spring for the Folder name

  • Then right click on the new folder WEB-INF/spring

  • Select New→File

  • Enter security.xml for the File name

  • Click Finish

  • Replace the contents of the file with the following:

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="password" authorities="ROLE_USER" />
	</user-service>

</b:beans>

Registering Spring Security with the war

We have created the Spring Security configuration, but we still need to register it with the war. This can be done using the following steps:

  • In the Package Explorer view, right click on the folder src/main/webapp/WEB-INF

  • Select New→File

  • Enter web.xml for the File name

  • Click Finish

  • Replace the contents of the file with the following:

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
  https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

	<!--
	  - Location of the XML file that defines the root application context
	  - Applied by ContextLoaderListener.
	  -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/spring/*.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>

	<!--
	  - Loads the root application context of this web app at startup.
	  - The application context is then available via
	  - WebApplicationContextUtils.getWebApplicationContext(servletContext).
	-->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

</web-app>

The web.xml will do the following things:

  • Registers the springSecurityFilterChain Filter for every URL in your application

  • Adds a ContextLoaderListener that loads the security-config-xml.

Exploring the secured application

Start the server as we did in Running the insecure application Now when you visit http://localhost:8080/sample/ you will be prompted with a login page that is automatically generated by Spring Security.

Authenticating to the secured application

Try entering an invalid username and password:

  • Username invalid

  • Password invalid

You should see an error message stating that authentication failed. Now try entering a valid username and password:

  • Username user

  • Password password

You should now see the page that we wanted to secure.

The reason we can successfully authenticate with Username user and Password password is because that is what we configured in our security-config-xml.

Displaying the user name

Now that we have authenticated, let’s update the application to display the username. Update the body of index.jsp to be the following:

src/main/webapp/index.jsp
<body>
  <div class="container">
    <h1>This is secured!</h1>
    <p>
      Hello <b><c:out value="${pageContext.request.remoteUser}"/></b>
    </p>
  </div>
</body>
The <c:out /> tag ensures the username is escaped to avoid XSS vulnerabilities Regardless of how an application renders user inputed values, it should ensure that the values are properly escaped.

Refresh the page at http://localhost:8080/sample/ and you will see the user name displayed. This works because Spring Security integrates with the Servlet API methods

Logging out

Now that we can view the user name, let’s update the application to allow logging out. Update the body of index.jsp to contain a log out form as shown below:

src/main/webapp/index.jsp
<body>
  <div class="container">
    <h1>This is secured!</h1>
    <p>
      Hello <b><c:out value="${pageContext.request.remoteUser}"/></b>
    </p>
    <c:url var="logoutUrl" value="/logout"/>
    <form class="form-inline" action="${logoutUrl}" method="post">
      <input type="submit" value="Log out" />
      <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
    </form>
  </div>
</body>

In order to help protect against CSRF attacks, by default, Spring Security Xml Configuration log out requires:

  • the HTTP method must be a POST

  • the CSRF token must be added to the request. You can access it on the ServletRequest using the attribute _csrf as illustrated above.

If you were using Spring MVC’s tag library or Thymeleaf, the CSRF token is automatically added as a hidden input for you.

Refresh the page at http://localhost:8080/sample/ and you will see the log out button. Click the logout button and see that the application logs you out successfully.

Conclusion

You should now know how to secure your application using Spring Security with XML. To learn more refer to the Spring Security Guides index page.