Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ricardomb-tech/auth-service/llms.txt

Use this file to discover all available pages before exploring further.

Auth Service supports federated login through Google (OpenID Connect) and GitHub (OAuth2). When a user authenticates through either provider, the service resolves the verified email from the provider’s identity token and either links it to an existing account or creates a new one — no separate registration step is needed. Federated identities are linked permanently to the internal account, so the same user can later log in with credentials or through any provider they have ever used.

Google OAuth2

Google is a full OpenID Connect (OIDC) provider. Auth Service reads the sub, email, and email_verified claims directly from the OIDC ID token — no secondary API call is needed.
1

Create an OAuth2 client in Google Cloud Console

  1. Open the Google Cloud Console and select (or create) a project.
  2. Navigate to APIs & Services → Credentials.
  3. Click Create Credentials → OAuth client ID.
  4. Choose Web application as the application type.
  5. Give the client a name (e.g. auth-service).
2

Set the authorized redirect URI

Under Authorized redirect URIs, add the callback URL for Auth Service:
http://your-host/login/oauth2/code/google
For local development this is:
http://localhost:8080/login/oauth2/code/google
This URI is handled internally by Spring Security — you do not need to write a controller for it. Do not add any other paths or query parameters.
3

Copy the credentials to your environment

After saving, Google displays the Client ID and Client Secret. Set them as environment variables:
GOOGLE_CLIENT_ID=<your-client-id>.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-<your-client-secret>
4

Verify the configured scopes

The following scopes are requested automatically by Auth Service. No additional configuration is required on the Google side for these standard scopes:
# application.properties
spring.security.oauth2.client.registration.google.scope=openid,email,profile
ScopePurpose
openidSignals OIDC flow; enables the ID token with sub and email_verified
emailIncludes the user’s email address in the token
profileIncludes basic profile information (name, picture)

GitHub OAuth2

GitHub is not an OIDC provider — it does not issue ID tokens and its GET /user endpoint does not expose whether an email is verified. Auth Service handles this with a custom GitHubOAuth2UserService that calls GET /user/emails after the base user is loaded and injects the primary verified email as synthetic email and email_verified attributes. The success handler then reads these attributes using the same code path as Google, so no provider-specific branching is needed downstream.
1

Create an OAuth App in GitHub

  1. Open GitHub Settings → Developer settings → OAuth Apps.
  2. Click New OAuth App.
  3. Fill in Application name, Homepage URL, and the callback URL (next step).
2

Set the callback URL

In the Authorization callback URL field, enter the Spring Security callback path for GitHub:
http://your-host/login/oauth2/code/github
For local development:
http://localhost:8080/login/oauth2/code/github
GitHub allows only a single callback URL per OAuth App. If you need separate URLs for development and production, create two separate OAuth Apps.
3

Copy the credentials to your environment

After registering the app, generate a Client Secret on the app’s settings page. Set both values:
GITHUB_CLIENT_ID=<your-github-client-id>
GITHUB_CLIENT_SECRET=<your-github-client-secret>
4

Verify the required scopes

Auth Service requests two scopes from GitHub:
# application.properties
spring.security.oauth2.client.registration.github.scope=read:user,user:email
ScopePurpose
read:userReads the public profile from GET /user (display name, avatar, etc.)
user:emailGrants access to GET /user/emailsrequired to retrieve the primary verified email
The user:email scope is mandatory. GitHub hides email addresses from GET /user by default and does not expose a verified status there. Without user:email, GitHubOAuth2UserService cannot call GET /user/emails to determine the primary verified email address, and the login will fail.

Redirect URI Configuration

After OAuth2 authentication succeeds or fails, Auth Service redirects the user’s browser to a frontend URL. These URLs are configurable and validated at startup by OAuth2RedirectProperties.
# application.properties
auth.oauth2.success-redirect-uri=${OAUTH2_SUCCESS_REDIRECT_URI}
auth.oauth2.failure-redirect-uri=${OAUTH2_FAILURE_REDIRECT_URI}
OAUTH2_SUCCESS_REDIRECT_URI
string
required
Frontend URL the browser is redirected to after a successful OAuth2 login. A short-lived, one-time code parameter is appended automatically by OAuth2AuthenticationSuccessHandler.Example: http://localhost:3000/oauth2/successThe resulting redirect will look like:
http://localhost:3000/oauth2/success?code=<one-time-exchange-code>
OAUTH2_FAILURE_REDIRECT_URI
string
required
Frontend URL the browser is redirected to when OAuth2 login fails — for example, because the user denied consent, the provider returned an error, or the email returned by the provider was not verified.Example: http://localhost:3000/oauth2/failure
Why a one-time exchange code instead of the JWT in the URL?After a successful OAuth2 login, OAuth2AuthenticationSuccessHandler issues a short-lived, single-use exchange code and redirects the browser to OAUTH2_SUCCESS_REDIRECT_URI?code=<code>. The frontend must then call POST /auth/oauth2/exchange with that code to receive the actual Access Token and Refresh Token pair.This indirection is intentional: placing JWTs directly in redirect URLs would expose them in the browser’s history, server and proxy access logs, and via the HTTP Referer header if the frontend page loads any external resources. The exchange code is meaningless on its own — it can only be redeemed once, and only by a request that arrives before it expires.

OAuth2 Flow Overview

Browser                  Auth Service            Google / GitHub
  │                           │                        │
  │  GET /oauth2/authorization/google                  │
  │──────────────────────────▶│                        │
  │                           │  302 → provider        │
  │◀──────────────────────────│                        │
  │                                                    │
  │  GET accounts.google.com/o/oauth2/auth?...         │
  │───────────────────────────────────────────────────▶│
  │                           User approves            │
  │◀───────────────────────────────────────────────────│
  │  302 → /login/oauth2/code/google?code=...          │
  │                                                    │
  │  GET /login/oauth2/code/google?code=...            │
  │──────────────────────────▶│                        │
  │                           │  exchange code for tokens
  │                           │───────────────────────▶│
  │                           │◀───────────────────────│
  │                           │  load user, link account
  │                           │  issue one-time exchange code
  │  302 → OAUTH2_SUCCESS_REDIRECT_URI?code=<otp>      │
  │◀──────────────────────────│                        │
  │                           │                        │
  │  POST /auth/oauth2/exchange  { code: <otp> }       │
  │──────────────────────────▶│                        │
  │  { accessToken, refreshToken, expiresIn }          │
  │◀──────────────────────────│                        │

application.properties Reference

The full OAuth2 provider mapping in application.properties for reference:
# Google — full OIDC provider
spring.security.oauth2.client.registration.google.client-id=${GOOGLE_CLIENT_ID}
spring.security.oauth2.client.registration.google.client-secret=${GOOGLE_CLIENT_SECRET}
spring.security.oauth2.client.registration.google.scope=openid,email,profile

# GitHub — non-OIDC; GitHubOAuth2UserService fetches verified email from GET /user/emails
spring.security.oauth2.client.registration.github.client-id=${GITHUB_CLIENT_ID}
spring.security.oauth2.client.registration.github.client-secret=${GITHUB_CLIENT_SECRET}
spring.security.oauth2.client.registration.github.scope=read:user,user:email

# Frontend redirect targets (validated at startup by OAuth2RedirectProperties)
auth.oauth2.success-redirect-uri=${OAUTH2_SUCCESS_REDIRECT_URI}
auth.oauth2.failure-redirect-uri=${OAUTH2_FAILURE_REDIRECT_URI}
Both redirect URI properties (auth.oauth2.success-redirect-uri and auth.oauth2.failure-redirect-uri) are parsed as java.net.URI at startup. If either value is blank or malformed, OAuth2RedirectProperties will throw an IllegalStateException and abort the application before any login attempt is ever made.

Build docs developers (and LLMs) love