Implementing OAuth2 in Spring Boot: A Step-by-Step Guide

Master OAuth2 in Spring Boot with our step-by-step guide! Secure your applications with practical code examples

In today’s interconnected digital landscape, securing applications and managing user authentication is paramount. One of the most robust and widely adopted protocols for authorization is OAuth2. Whether you’re building a web application, mobile app, or any service that requires user authentication, understanding OAuth2 is essential.

This guide will walk you through implementing OAuth2 in a Spring Boot application, focusing on the authorization_code grant type. We’ll break down the concepts, explore why OAuth2 is important, and provide clear Java code examples to help you get started, even if you’re a beginner.

What is OAuth2 and Why is it Important?

OAuth2 (Open Authorization 2) is an industry-standard protocol for authorization. It allows applications to obtain limited access to user accounts on an HTTP service, such as Facebook, GitHub, or Google, without exposing user credentials.

Key Benefits of OAuth2:

  1. Security: OAuth2 ensures that user credentials are never shared with third-party applications.
  2. Flexibility: It supports various use cases through different grant types.
  3. Scalability: Suitable for applications of all sizes, from small startups to large enterprises.

Understanding OAuth2 is crucial for developers aiming to implement secure and efficient authentication mechanisms in their applications.

OAuth2 Grant Types

OAuth2 defines several grant types, each suited to different scenarios:

  1. Authorization Code: Suitable for server-side applications. It involves exchanging an authorization code for an access token.
  2. Implicit: Designed for client-side applications, where tokens are directly returned without an intermediate code.
  3. Resource Owner Password Credentials: Allows exchanging user credentials for tokens. Typically used in highly trusted applications.
  4. Client Credentials: For machine-to-machine authentication without user involvement.

While OAuth2 supports multiple grant types, this guide will focus on the Authorization Code grant type, which is the most secure and widely used for web applications.

Getting Started with OAuth2 in Spring Boot

Let’s dive into implementing OAuth2 in a Spring Boot application using the authorization_code grant type.

Prerequisites

  • Java Development Kit (JDK) 11 or higher
  • Spring Boot 2.7+
  • Maven or Gradle build tool
  • An OAuth2 provider account (e.g., Google, GitHub)

Step 1: Setting Up Your Spring Boot Project

First, create a new Spring Boot project using Spring Initializr:

  • Project: Maven Project
  • Language: Java
  • Spring Boot: 2.7.x or higher
  • Dependencies:

– Spring Web
– Spring Security
– OAuth2 Client
– Thymeleaf (optional, for view rendering)

Download the project and import it into your IDE.

Step 2: Configuring OAuth2 Client

In your application.properties or application.yml, configure the OAuth2 client settings. Here’s an example using Google as the OAuth2 provider:

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: YOUR_GOOGLE_CLIENT_ID
            client-secret: YOUR_GOOGLE_CLIENT_SECRET
            scope: profile, email
        provider:
          google:
            authorization-uri: <https://accounts.google.com/o/oauth2/v2/auth>
            token-uri: <https://www.googleapis.com/oauth2/v4/token>
            user-info-uri: <https://www.googleapis.com/oauth2/v3/userinfo>
            user-name-attribute: sub

Note: Replace YOUR_GOOGLE_CLIENT_ID and YOUR_GOOGLE_CLIENT_SECRET with your actual credentials from the OAuth2 provider.

Step 3: Creating Security Configuration

Create a security configuration class to handle OAuth2 login and protect your endpoints.

package com.example.oauth2demo.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.web.SecurityFilterChain;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeRequests(authorize -> authorize
                .antMatchers("/", "/login").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2Login(oauth2 -> oauth2
                .loginPage("/login")
                .defaultSuccessURL("/home", true)
            );
        return http.build();
    }

}

Step 4: Creating Controllers

Create controllers to handle the landing page, login, and home page.

package com.example.oauth2demo.controller;

import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MainController {

    @GetMapping("/")
    public String index() {
        return "index"; // Return index.html
    }

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

    @GetMapping("/home")
    public String home(OAuth2AuthenticationToken authentication, Model model) {
        model.addAttribute("user", authentication.getPrincipal().getAttributes());
        return "home"; // Return home.html
    }

}

Step 5: Creating Views

Using Thymeleaf, create simple HTML templates for index.htmllogin.html, and home.html.

index.html

<!DOCTYPE html>
<html xmlns:th="<http://www.thymeleaf.org>">
<head>
    <title>OAuth2 Demo</title>
</head>
<body>
    <h1>Welcome to OAuth2 Demo</h1>
    <a href="/login">Login with Google</a>
</body>
</html>

login.html

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

home.html

<!DOCTYPE html>
<html xmlns:th="<http://www.thymeleaf.org>">
<head>
    <title>Home</title>
</head>
<body>
    <h1>Home</h1>
    <p>Welcome, <span th:text="${user['name']}"></span>!</p>
    <p>Email: <span th:text="${user['email']}"></span></p>
    <a href="/logout">Logout</a>
</body>
</html>

Step 6: Running the Application

Run your Spring Boot application. Navigate to http://localhost:8080/ and click the “Login with Google” link. You should be redirected to Google’s OAuth2 consent screen. Upon successful authentication, you’ll be redirected to the home page displaying your user information.

Enhancing the Application

Handling Different OAuth2 Providers

You can configure multiple OAuth2 providers by adding their configurations to your application.yml or application.properties. For example, to add GitHub:

spring:
  security:
    oauth2:
      client:
        registration:
          github:
            client-id: YOUR_GITHUB_CLIENT_ID
            client-secret: YOUR_GITHUB_CLIENT_SECRET
            scope: read:user
        provider:
          github:
            authorization-uri: <https://github.com/login/oauth/authorize>
            token-uri: <https://github.com/login/oauth/access_token>
            user-info-uri: <https://api.github.com/user>
            user-name-attribute: id

Customizing User Information

You can customize how user information is processed by implementing a custom OAuth2UserService.

package com.example.oauth2demo.service;

import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;

@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        OAuth2User user = super.loadUser(userRequest);
        // Add custom processing here
        return user;
    }

}

Then, update your SecurityConfig to use the custom user service:

.oauth2Login(oauth2 -> oauth2
    .userInfoEndpoint(userInfo -> userInfo
        .userService(customOAuth2UserService)
    )
    .loginPage("/login")
    .defaultSuccessURL("/home", true)
)

Conclusion

Implementing OAuth2 in Spring Boot using the authorization_code grant type is a powerful way to secure your applications and manage user authentication efficiently. By following this step-by-step guide, you can set up OAuth2 with a popular provider like Google and customize it to fit your specific needs.

As you grow more comfortable with OAuth2, you can explore other grant types and more advanced configurations to enhance the security and functionality of your applications. Happy coding!