Basic structure with Spring Boot
We will use Spring Boot to quickly generate a Java project with Spring Security. Go to https://start.spring.io/ and select the Web, Thymeleaf and Security dependencies. By clicking on “Switch to the full version” we can stablish the values for group, artifact, etc. Click on “Generate Project”, unzip the downloaded file and import it in Eclipse with “Import as Maven Project”. Wait until the dependencies are downloaded and in this moment we will have the base structure.
Templates
Let’s generate the Thymeleaf templates to show the content of our Web application. We need three files: 1. An index as main page. 2. A login page that will allow users to authenticate. 3. A protected page. Put these files in the src/main/resources/templates route.
index.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Spring Security Demo Index page</title> </head> <body> <a th:href="@{/protected}">Go to protected page</a> </body> </html>
login.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Spring Security Demo Login page</title> </head> <body> <div th:if="${param.error}">Invalid username and password.</div> <div th:if="${param.logout}">You have been logged out.</div> <form th:action="@{/login}" method="post"> <div> <label> User Name : <input type="text" name="username" /> </label> </div> <div> <label> Password: <input type="password" name="password" /> </label> </div> <div> <input type="submit" value="Sign In" /> </div> </form> </body> </html>
protected.html
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"> <head> <title>Spring Security Demo Protected page</title> </head> <body> <h1 th:inline="text">Hello [[${#httpServletRequest.remoteUser}]]!</h1> <form th:action="@{/logout}" method="post"> <input type="submit" value="Sign Out" /> </form> </body> </html>
Configuration
Now we have to tell the Thymeleaf’s ViewResolver what URLs are mapped to what pages, to let it redirect the user. From version 3.2 we can use annotations, that avoid the necessity of using any XML to configure Spring Security. Create the following file:
package com.luisgomezcaballero.springsecuritydemo; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration public class MvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/index").setViewName("index"); registry.addViewController("/").setViewName("index"); registry.addViewController("/protected").setViewName("protected"); registry.addViewController("/login").setViewName("login"); } }
After that, we have to configure the request security by specifying what resources will be protected and what resources will not. To do this we create a user in memory with its username, password and role.
package com.luisgomezcaballero.springsecuritydemo; 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; @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().antMatchers("/", "/index").permitAll().anyRequest().authenticated().and().formLogin() .loginPage("/login").permitAll().and().logout().permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("admin").password("password").roles("ADMIN"); } }
Demonstration
Right click on SpringSecurityDemoApplication and Run As Java Application. EIn the Console tab we will se how the embedded Tomcat server is starting. Once finished, go to http://localhost:/8080. Click on the link and, as it’s a protected resource, it will ask for username and password. If we fail, a error message will be shown. If we login correctly we will be see the content of the protected page.
Repository
This demonstration project can be located at https://github.com/luisgomezcaballero/spring-security-demo.
So, what do you think ?