Spring Boot Backend Development Course, Implementing Login and Logout with OAuth2, Resolving Test Code Failures and Modifying Code

Implementing Login/Logout with OAuth2

Spring Boot is a Java-based web application development framework that provides powerful and flexible features.
In this tutorial, we will learn how to implement secure login and logout functionality using OAuth2.
OAuth2 is a protocol that allows client applications to safely access data from resource servers.
This allows for complete user authentication management.

1. Project Setup

Use Spring Initializr (https://start.spring.io/) to create a new project.
The necessary dependencies are as follows:

  • Spring Web
  • Spring Security
  • OAuth2 Client
  • Spring Data JPA
  • H2 Database (for testing)

Check the build.gradle or pom.xml file of the generated project using Maven or Gradle to ensure it is set up correctly.

2. OAuth2 Configuration

Add OAuth2 client configuration to the application.yml file.
For example, if using Google OAuth2, you can set it up as follows:

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: YOUR_CLIENT_ID
            client-secret: YOUR_CLIENT_SECRET
            scope:
              - profile
              - email
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
        provider:
          google:
            authorization-uri: https://accounts.google.com/o/oauth2/auth
            token-uri: https://oauth2.googleapis.com/token
            user-info-uri: https://www.googleapis.com/oauth2/v3/userinfo
            user-name-attribute: sub

3. Security Configurations

Configure security by extending the WebSecurityConfigurerAdapter class.
You can set up how to handle the login page and results.

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("/", "/oauth2/**", "/login**").permitAll()
                .anyRequest().authenticated()
                .and()
            .oauth2Login()
                .loginPage("/login")
                .defaultSuccessUrl("/", true);

        // Logout configuration
        http.logout()
            .logoutSuccessUrl("/")
            .permitAll();
    }
}

4. Login and Logout Handling Controller

Next, implement a Controller to handle login and logout requests.
Below is an example of a basic Controller:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {
    
    @GetMapping("/login")
    public String login() {
        return "login"; // Return to login.html
    }
}

5. Implementing Login & Logout Pages

Implement the login page using Thymeleaf or JSP.
Below is an example using Thymeleaf:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Login</title>
</head>
<body>
    <h1>Login Page</h1>
    <a href="@{/oauth2/authorization/google}">Login with Google</a>
</body>
</html>

Resolving Test Code Failures and Modifying Code

After implementing OAuth2 login handling, you need to write test code to confirm that the functionality works correctly.
However, the initially written tests may fail. This section explains how to identify and correct the reasons for failure.

1. Writing Test Code

Write code to test OAuth2 login using Spring Test. Below is an example of basic test code:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest
@AutoConfigureMockMvc
public class LoginControllerTest {
    
    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithMockUser
    public void testLoginPage() throws Exception {
        mockMvc.perform(get("/login"))
            .andExpect(status().isOk());
    }
}

2. Analyzing Causes of Failure

If the tests fail, there may be various reasons for this.
The most common issues are authentication or path configuration problems. For instance, the URL for the login page may be incorrectly specified or
set to prevent access for unauthenticated users, causing the failure.

3. Example of Code Modification

If the test expects a login page but the page does not exist, you need to modify the login page path.
You may need to revise the Controller as follows.

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {
    
    @GetMapping("/login")
    public String login() {
        return "login"; // Return to login.html
    }
}

4. Rerun Tests

After modifying the code, rerun the tests to check if they succeed.

Conclusion

In this tutorial, we learned how to implement login/logout functionality using OAuth2 with Spring Boot, as well as how to write and modify test code.
OAuth2 is a critical element in modern web applications and helps to enhance security.
Additionally, writing test code to verify that functionality works correctly is a very important process in software development.
This allows us to develop stable and secure applications.