DEV Community

DevCorner2
DevCorner2

Posted on

Step-by-step guide to implementing OAuth 2.0 Authentication in a Spring Boot application, in a clean, structured way

Here’s a step-by-step guide with full code to implement OAuth2 authentication in a Spring Boot application using Spring Security, structured in a modular and clean way.

We will demonstrate using Google as an OAuth2 provider, but the structure can be adapted for GitHub, Facebook, Okta, etc.


✅ Project Structure

oauth2-demo/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/example/oauth2demo/
│   │   │       ├── config/
│   │   │       │   └── SecurityConfig.java
│   │   │       ├── controller/
│   │   │       │   └── HomeController.java
│   │   │       ├── model/
│   │   │       ├── service/
│   │   │       └── Oauth2DemoApplication.java
│   │   └── resources/
│   │       ├── application.yml
│   │       └── templates/
│   │           └── home.html
├── pom.xml
Enter fullscreen mode Exit fullscreen mode

1️⃣ Create the Spring Boot Project

Generate a Spring Boot project with:

  • Spring Web
  • Spring Security
  • OAuth2 Client
  • Thymeleaf (for UI rendering)

You can use Spring Initializr: https://start.spring.io


2️⃣ pom.xml

Add these dependencies:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-oauth2-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
Enter fullscreen mode Exit fullscreen mode

3️⃣ application.yml

server:
  port: 8080

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

Replace YOUR_GOOGLE_CLIENT_ID and YOUR_GOOGLE_CLIENT_SECRET with values from Google Developer Console.


4️⃣ SecurityConfig.java

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;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/", "/login**", "/css/**").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2Login(oauth2 -> oauth2
                .loginPage("/login")
                .defaultSuccessUrl("/home", true)
            );
        return http.build();
    }
}
Enter fullscreen mode Exit fullscreen mode

5️⃣ HomeController.java

package com.example.oauth2demo.controller;

import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

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

    @GetMapping("/home")
    public String home(Model model, @AuthenticationPrincipal OAuth2User principal) {
        model.addAttribute("name", principal.getAttribute("name"));
        model.addAttribute("email", principal.getAttribute("email"));
        model.addAttribute("picture", principal.getAttribute("picture"));
        return "home";
    }

    @GetMapping("/login")
    public String login() {
        return "login";
    }
}
Enter fullscreen mode Exit fullscreen mode

6️⃣ Thymeleaf Templates

templates/index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Welcome</title>
</head>
<body>
    <h2>Welcome to the OAuth2 Demo App</h2>
    <a href="/oauth2/authorization/google">Login with Google</a>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

templates/home.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>User Home</title>
</head>
<body>
    <h2>Welcome, <span th:text="${name}">User</span></h2>
    <img th:src="${picture}" alt="Profile Picture" width="100"/>
    <p>Email: <span th:text="${email}">[email protected]</span></p>
    <a href="/logout">Logout</a>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

templates/login.html (Optional)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Login</title>
</head>
<body>
    <h2>Login Page</h2>
    <a href="/oauth2/authorization/google">Login with Google</a>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

✅ Running the App

  1. Run the app: ./mvnw spring-boot:run
  2. Visit http://localhost:8080
  3. Click “Login with Google”
  4. Approve permissions
  5. You'll be redirected to /home with user info displayed

✅ Next Steps

  • Store user details in a database (JPA + User entity)
  • Add multiple OAuth providers (e.g., GitHub, Facebook)
  • Use custom OAuth2UserService to map user details

Top comments (0)