Last updated on March 9th, 2024
In this example, we will learn how to customise Spring Security in Login and Logout in Spring Boot example. Spring Security provides a default login form and logout feature. We will create a step-by-step Spring Boot application with Spring Security to customize a login and logout feature.
Table of content
1. Keep Eclipse IDE ready(STS integrated)
2. Create a Spring Boot Starter Project
3. Maven Dependency
4. Create a view page
5. Create a Controller class
6. Create a Spring Security Config class
7. Run the Application
8. How to use different field names and URL in Login in Spring Security?
9. Login Success Handler
10. Logout Success Handler
11. Conclusion
1. Keep Eclipse IDE ready(STS integrated)
Refer to this article How to Create Spring Project in IDE to create Spring Boot Project in Eclipse IDE.
2. Create a Spring Boot Starter Project
Add the following dependencies:
• Spring Web
• Spring Security
• Thymeleaf
Project Structure of Spring Security in Login and Logout in Spring Boot
3. Maven Dependency
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.11</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springjava</groupId>
<artifactId>Spring_Security_Custom_Login_Logout_Example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Spring_Security_Custom_Login_Logout_Example</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>16</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4. Create a view page
Create a view page under src/main/resources/templates.
login.html
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand">Spring Security
Custom Login-Logout Example</a>
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
</div>
</nav>
<br />
<br />
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3">
<div th:if="${param.error}">
<div class="alert alert-danger">Invalid Username or Password</div>
</div>
<div th:if="${param.logout}">
<div class="alert alert-success">You have been logged out.</div>
</div>
<div class="card">
<div class="card-header">
<h2 class="text-center">Login</h2>
</div>
<div class="card-body">
<form method="post" role="form" th:action="@{/login}"
class="form-horizontal">
<div class="form-group mb-3">
<label class="control-label"> Username</label> <input type="text"
id="username" name="username" class="form-control"
placeholder="Enter username" />
</div>
<div class="form-group mb-3">
<label class="control-label"> Password</label> <input
type="password" id="password" name="password"
class="form-control" placeholder="Enter password" />
</div>
<div class="form-group mb-3">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
home.html
<html lang="en"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Home</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand">Spring Security Custom Login-Logout Example</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" th:href="@{/logout}">Logout</a>
</li>
</ul>
</div>
</div>
</nav>
<br /><br />
<body>
<div class="container">
<div class="row">
<h1> Welcome to Spring Security world!</h1>
</div>
</div>
</body>
</html>
5. Create a Controller class
HomeController.java
package com.springjava.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping("/")
public String greeting() {
return "home";
}
@GetMapping("/login")
public String login() {
return "login";
}
}
6. Create a Spring Security Config class
SecurityConfig.java
package com.springjava.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public static PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityChain(HttpSecurity http) throws Exception {
http.csrf().disable().
authorizeRequests().anyRequest().authenticated()
.and().formLogin().loginPage("/login")
.and().formLogin().loginProcessingUrl("/login")
.and().formLogin().defaultSuccessUrl("/").permitAll()
.and().logout().logoutSuccessUrl("/login");
return http.build();
}
@Bean
public UserDetailsService userDetailsService() {
UserDetails admin = User.builder().username("admin").password(passwordEncoder().encode("admin")).roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(admin);
}
}
7. Run the Application
To run this application right-click on the application click on Run As then select the Run on Server option. After successfully running this application on the browser custom login form is shown.
Custom Login Form
Enter a valid username and password then click on the Login button of the form.
Click on the Logout to check the custom logout feature.
Enter an invalid username and password to check the error message.
8. How to use different field names and URL in Login in Spring Security?
Spring Security by default uses the field names username and password and the action of the form “/login”. If we want to use customised field names and URL for login we can specify like code below:
http.formLogin()
.loginPage("/login")
.usernameParameter("email")
.passwordParameter("pass")
.loginProcessingUrl("/do-login");
<form th:action="@{/do-login}" method="post">
<p>
E-mail: <input type="email" name="email" required />
</p>
<p>
Password: <input type="password" name="pass" required />
</p>
<p>
<input type="submit" value="Login" />
</p>
</form>
9. Login Success Handler
We can also write code with a success handler for login customization in Spring Security. We can follow like below:
http.formLogin()
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
System.out.println("Logged user: " + authentication.getName());
response.sendRedirect("/");
}
});
10. Logout Success Handler
We can also write code with a logout success handler for logout customization in Spring Security. We can follow like below:
http.logout().
logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
System.out.println("User logged out: " + authentication.getName());
response.sendRedirect("/login");
}
});
11. Conclusion
In this example, we learnt how to use customise Spring Security login and logout in the Spring Boot application.