Spring Boot Backend Development Course, Implementing Login and Logout with Spring Security, User Registration, Testing Login and User Registration

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.

  1. Access Spring Initializr in your web browser.
  2. 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
  3. Select the following under Dependencies.
    • Spring Web
    • Spring Security
    • Spring Data JPA
    • H2 Database
  4. 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!