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.