life is too short for a diary




Getting Started with Oauth2

Tags: oauth2 java spring boot

Author
Written by: Tushar Sharma
Featured image for Getting Started with Oauth2

OAuth2 is an authorization framework that enables applications to access resources on behalf of a user without exposing their credentials. It is not an authentication protocol by itself — it delegates authorization securely.

Why OAuth2?

Imagine an app that needs access to your Gmail. Instead of asking for your password (a security risk), it redirects you to Google’s login page. After you log in, Google issues a token to the app. The app uses this token to access your data — you never shared your password.

This is OAuth2 in action: secure, delegated access

Core OAuth2 Flow (Authorization Code Flow)

  1. Redirect to /authorize endpoint The app redirects the user to the authorization server (e.g., Google, Okta). Example:
https://accounts.google.com/oauth2/authorize?
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  response_type=code&
  scope=email profile
  1. User logs in and consents The identity provider authenticates the user and asks for permission.

  2. Authorization server redirects with a code On success, it sends a one-time-use authorization code to the redirect_uri

  3. App exchanges code for tokens The backend calls the /token endpoint:

POST /token
Body: client_id, client_secret, code, redirect_uri, grant_type=authorization_code

Response includes:

  1. Use access token Include in requests as:
Authorization: Bearer <access_token>

Key Concepts

OAuth2 vs OpenID Connect (OIDC)

OIDC introduces:

Common OAuth2 Flows

Flow Use Case Client Type Security Notes
Authorization Code Web applications with a backend Confidential Recommended for server-side apps
Authorization Code + PKCE Single-Page Apps (SPAs), mobile apps Public Secure against code interception; required for SPAs
Client Credentials Machine-to-machine (M2M) communication Confidential For service accounts, not end-user access
Implicit (Legacy) Older SPAs (no backend) Public ❌ Deprecated — do not use
Resource Owner Password Credentials Trusted first-party apps only Confidential Only if absolutely necessary; avoid in favor of OAuth2 flows

When to Use Which Flow?

OAuth2 in Java Spring Boot

Using token from UI

If your UI already has an access token:

@Repository
public class Repository {

    private final WebClient webClient;

    public Repository(WebClient.Builder webClientBuilder) {
        this.webClient = webClientBuilder
                          .baseUrl("URL")
                          .filter(new ServerBearerExchange(FilterFunction))
                          .build();
    }
}

Using Client Credentials Flow

in application.yaml

api:
  auth2:
    provider:
      issuer-uri: "https://auth-server.com/oauth2"
    client:
      client-id: "CLIENT_ID"
      client-secret: "CLIENT_SECRET"
      authorization-grant-type: client_credentials
      scope: "read write"

Set up a reactive WebClient that automatically fetches and attaches OAuth2 tokens using client credentials.

@Configuration
public class WebClientConfig {

    @Bean
    public WebClient webClient(WebClient.Builder webClientBuilder,
                               @Value("${apis.url}") String apiUrl,
                               @Value("${api.auth2.provider.issuer-uri}") String issuerUri,
                               @Value("${api.auth2.client.client-id}") String clientId,
                               @Value("${api.auth2.client.client-secret}") String clientSecret,
                               @Value("${api.auth2.client.scope}") String scope) {

        ClientRegistration clientRegistration = ClientRegistration
                .withRegistrationId("instrument-api")
                .tokenUri(issuerUri + "/v1/token")
                .clientId(clientId)
                .clientSecret(clientSecret)
                .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
                .scope(scope)
                .build();

        ReactiveClientRegistrationRepository clientRegistrations =
                new InMemoryReactiveClientRegistrationRepository(clientRegistration);

        ReactiveOAuth2AuthorizedClientService authorizedClientService =
                new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrations);

        return webClientBuilder
                .filter(new ServerOAuth2AuthorizedClientExchangeFilterFunction(
                        new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
                                clientRegistrations, authorizedClientService)))
                .baseUrl(apiUrl)
                .defaultHeader("Content-Type", "application/json")
                .build();
    }
}


comments powered by Disqus