Information Security 17 min read

Understanding OAuth2: Concepts, Grant Types, and Spring Boot Implementation

This article explains the OAuth2 authorization framework, illustrates its principles with a delivery‑person analogy, details the four main grant types, and provides a step‑by‑step Spring Boot implementation including server configuration, resource protection, and Postman testing.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding OAuth2: Concepts, Grant Types, and Spring Boot Implementation

OAuth (Open Authorization) is an open standard that lets users grant third‑party applications access to their resources without sharing passwords; OAuth2 is the newer, non‑backward‑compatible version.

Analogy

The author compares OAuth2 to a residential complex where a delivery person needs temporary, limited access via a token instead of the resident’s permanent password.

Design of the Authorization Mechanism

Step 1: Add a "Get Authorization" button to the gate’s password entry.

Step 2: The resident receives a dialog on their phone to approve the request.

Step 3: After approval, the gate issues a short‑lived access token.

Step 4: The delivery person presents the token to the gate.

This mirrors OAuth2’s token‑based access control.

Key Roles in OAuth2

Resource Owner : the user who authorizes access.

Client : the third‑party application requesting access.

Authorization Server : validates the user and issues tokens.

Resource Server : hosts the protected resources.

OAuth2 Grant Types

Authorization Code : most complete, involves server‑to‑server exchange.

Implicit (Simplified) : token returned directly to browser, no refresh token.

Password : client sends user credentials; suitable for legacy systems.

Client Credentials : client authenticates with its own ID/secret, ideal for micro‑service APIs.

Spring Boot Implementation Steps

1. Add Dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>2.3.3.RELEASE</version>
</dependency>

2. Configure Authorization Server

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    @Autowired AuthenticationManager authenticationManager;
    @Autowired(required = false) TokenStore inMemoryTokenStore;
    @Autowired UserDetailsService userDetailsService;
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("password")
            .authorizedGrantTypes("password", "refresh_token")
            .accessTokenValiditySeconds(1800)
            .resourceIds("rid")
            .scopes("all")
            .secret("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq");
    }
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints){
        endpoints.tokenStore(inMemoryTokenStore)
                 .authenticationManager(authenticationManager)
                 .userDetailsService(userDetailsService);
    }
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security){
        security.allowFormAuthenticationForClients();
    }
}

3. Configure Resource Server

import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(ResourceServerSecurityConfigurer resources){
        resources.resourceId("rid").stateless(true);
    }
    @Override
    public void configure(HttpSecurity http) throws Exception{
        http.csrf().disable().authorizeRequests()
            .antMatchers("/admin/**").hasRole("admin")
            .antMatchers("/user/**").hasRole("user")
            .antMatchers("/secure/**").authenticated()
            .anyRequest().permitAll();
    }
}

4. Configure Spring Security

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.context.annotation.Bean;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    @Bean
    @Override
    protected UserDetailsService userDetailsService(){
        return super.userDetailsService();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.inMemoryAuthentication()
            .withUser("admin").password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq").roles("admin")
            .and()
            .withUser("sang").password("$2a$10$RMuFXGQ5AtH4wOvkUqyvuecpqUSeoxZYqilXzbz50dceRsga.WYiq").roles("user");
    }
    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.antMatcher("/oauth/**").authorizeRequests()
            .antMatchers("/oauth/**").permitAll()
            .and().csrf().disable();
    }
}

5. Test with Postman

Obtain an access_token via POST to oauth/token with username, password, grant_type, client_id, scope and client secret. Use the token to call protected resources; refresh it with a refresh_token when it expires. Unauthorized requests return an error.

Grant Type Summary

Password : sends user credentials; not recommended for new projects.

Authorization Code : redirects user to login, returns a code, then exchanges it for a token.

Implicit : token returned directly to browser; no refresh token.

Client Credentials : client authenticates with its own ID/secret; ideal for micro‑service APIs.

Overall, OAuth2 provides short‑lived, revocable tokens with scoped permissions, improving security over static passwords.

MicroservicesSpring BootsecurityOAuth2Authorizationaccess tokenGrant Types
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.