Implementing Login/Logout and User Registration with Spring Security
Hello, today we will conduct a backend development course using Spring Boot. In this course, we will take a detailed look at how to implement login and logout functionalities, as well as user registration using Spring Security. Spring Boot is a framework that allows for rapid and easy development of Java-based web applications, and we will be covering the process of building powerful and secure web applications through it.
1. Setting Up the Development Environment
Before we start the course, we need to set up the development environment. Below are the necessary tools and setup methods.
- Java Development Kit (JDK) 11 or higher
- Spring Boot 2.5.x or higher
- IDE such as IntelliJ IDEA or Eclipse
- Gradle or Maven (build tool)
- H2 Database (embedded database)
2. Creating a Spring Boot Project
To create a Spring Boot project, we will use Spring Initializr. Please follow the steps below to set up the project.
- Access Spring Initializr in your web browser.
- Enter the project metadata.
- Project: Maven Project or Gradle Project
- Language: Java
- Spring Boot: Set to 2.x.x
- Group: com.example
- Artifact: demo
- Name: demo
- Description: Spring Boot demo project
- Package name: com.example.demo
- Packaging: Jar
- Java: 11
- Select the following under Dependencies.
- Spring Web
- Spring Security
- Spring Data JPA
- H2 Database
- Click the Generate button to download the project ZIP file.
3. Project Structure
When you open the project, a basic package structure is created. Here’s an explanation of the roles of the main directories and files.
- src/main/java/com/example/demo: Directory where Java source files are located.
- src/main/resources/application.properties: Application settings file.
- src/test/java/com/example/demo: Directory where test files are located.
4. Configuring Spring Security
We will set up Spring Security to implement the login and logout functionalities.
4.1 Adding Dependencies
Add the necessary dependencies to the pom.xml or build.gradle file. If you are using Maven, please add the following dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
4.2 Creating SecurityConfig Class
Create a SecurityConfig class to define the configuration for Spring Security.
package com.example.demo.config;
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.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/register", "/h2-console/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
public void init() {
// Configuration for using H2 Console
java.sql.Connection conn = DriverManager.getConnection("jdbc:h2:mem:testdb", "sa", "");
conn.createStatement().execute("SET MODE MySQL");
}
}
5. Implementing User Registration Functionality
Now we will implement basic user registration functionality.
5.1 Creating User Entity
Create a User entity class to store user information.
package com.example.demo.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
// getters and setters
}
5.2 Creating UserRepository Interface
Create a UserRepository to manage user information.
package com.example.demo.repository;
import com.example.demo.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository {
User findByUsername(String username);
}
5.3 Creating UserService Class
Create a UserService class to handle the user registration logic.
package com.example.demo.service;
import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private BCryptPasswordEncoder passwordEncoder;
public void register(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
userRepository.save(user);
}
public User findByUsername(String username) {
return userRepository.findByUsername(username);
}
}
5.4 Creating RegistrationController Class
Create a RegistrationController class to handle the user registration page and logic.
package com.example.demo.controller;
import com.example.demo.model.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
@Controller
public class RegistrationController {
@Autowired
private UserService userService;
@GetMapping("/register")
public String showRegistrationForm(Model model) {
model.addAttribute("user", new User());
return "register";
}
@PostMapping("/register")
public String registerUser(@ModelAttribute User user) {
userService.register(user);
return "redirect:/login";
}
}
5.5 Creating HTML View Template
Create the user registration HTML view. Write the following in the templates/register.html file.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>User Registration</title>
</head>
<body>
<h1>User Registration</h1>
<form action="#" th:action="@{/register}" th:object="${user}" method="post">
<div>
<label for="username">Username:</label>
<input type="text" th:field="*{username}" required/>
</div>
<div>
<label for="password">Password:</label>
<input type="password" th:field="*{password}" required/>
</div>
<div>
<button type="submit">Register</button>
</div>
</form>
</body>
</html>
6. Implementing Login Functionality
Now we will implement the login feature. Since Spring Security handles user authentication, we only need to implement parts related to user information.
6.1 Modifying SecurityConfig
Set the user authentication information in SecurityConfig.
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService())
.passwordEncoder(passwordEncoder());
}
6.2 Implementing UserDetailsService
Create a UserDetailsService to handle user authentication information.
package com.example.demo.service;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userService.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("Cannot find user: " + username);
}
return org.springframework.security.core.userdetails.User.withUsername(user.getUsername())
.password(user.getPassword())
.roles("USER")
.build();
}
}
7. Login and Logout Pages
Implement the login page and logout confirmation page.
7.1 Creating login.html Template
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form action="#" th:action="@{/login}" method="post">
<div>
<label for="username">Username:</label>
<input type="text" name="username" required/>
</div>
<div>
<label for="password">Password:</label>
<input type="password" name="password" required/>
</div>
<div>
<button type="submit">Login</button>
</div>
</form>
</body>
</html>
7.2 Creating logout.html Template
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Logout</title>
</head>
<body>
<h1>You have been logged out.</h1>
<a href="/login">Go to login page</a>
</body>
</html>
8. Running and Testing
Now that we have completed all the settings and implementations, let’s run and test the application.
8.1 Running the Application
Run the application. Execute the following command through the IDE’s Run command or Terminal.
./mvnw spring-boot:run
In the browser, enter http://localhost:8080/register to navigate to the user registration page.
8.2 Testing User Registration
Test user registration by entering a username and password. After registration, proceed to http://localhost:8080/login and test the login functionality.
8.3 Testing Login and Logout
After logging in successfully, click the logout button to check if the logout works properly.
9. Conclusion
In this course, we learned how to implement login, logout, and user registration functions using Spring Security with Spring Boot. With these fundamental features, you have laid the foundation for securely operating your own web application. Explore additional features using Spring Boot to develop a more advanced web application!