skip to content

OAuth2 / OIDC Login

oauth2Login() runs the authorization-code flow against a registered provider and gives you an OAuth2User or OidcUser, with a user service you can extend to map to a local account. Interviewers ask how the first login creates a user in your own database.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What does oauth2Login() enable in a Spring Security application, and what OAuth2 flow does it use?

level: juniorimportance: must knowfreq 70%

answer

  1. Redirect -> code -> token exchange -> userinfo
  2. Callback /login/oauth2/code/{registrationId}
  3. OIDC adds id_token + nonce
  4. Login vs Client vs ResourceServer
  5. OAuth2AuthenticationToken in SecurityContext

basics

~20 s

oauth2Login() lets users sign in to your app using an external provider like Google or GitHub. It uses the OAuth2 authorization-code flow: Spring redirects the user to the provider, gets a code back, and exchanges it for tokens to log the user in.

solid answer

~40 s

oauth2Login() configures Spring Security to authenticate users via an external OAuth2/OIDC provider (Google, GitHub, Okta, etc.) using the authorization-code grant. The browser is redirected to the provider's authorization endpoint; after the user consents, the provider redirects back to Spring's /login/oauth2/code/{registrationId} callback with an authorization code. Spring exchanges that code (server-to-server) at the token endpoint for an access token (and, for OIDC, an id_token), then calls a userinfo endpoint to load the user. The result is an OAuth2AuthenticationToken in the SecurityContext holding an OAuth2User/OidcUser principal. It differs from oauth2ResourceServer() (which validates bearer tokens on APIs) and oauth2Client() (which only obtains tokens for calling downstream APIs, not for login).

code

java · 27 lines
java
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/", "/error").permitAll()
                .anyRequest().authenticated())
            // Enables the authorization-code login flow; Boot auto-builds
            // a provider-selection page and the /login/oauth2/code/* callback.
            .oauth2Login(Customizer.withDefaults());
        return http.build();
    }
}

// application.yml
// spring:
//   security:
//     oauth2:
//       client:
//         registration:
//           google:
//             client-id: ${GOOGLE_CLIENT_ID}
//             client-secret: ${GOOGLE_CLIENT_SECRET}
//             scope: openid, profile, email

go deeper

for a junior

Know it means 'Sign in with Google/GitHub' and that there's a redirect and a code exchanged for tokens.

for a middle

Explain the full authorization-code sequence including the state param and the /login/oauth2/code/{id} callback, and OIDC's id_token.

for a senior

Contrast login vs client vs resource-server, explain why code-flow over implicit, and the security roles of state and nonce.

for a principal

Reason about topology choices (BFF for SPAs), session vs stateless, token storage, and provider federation across many registrations.

**What it is.** `oauth2Login()` is a DSL method on `HttpSecurity` that turns your app into an OAuth2/OIDC *client* that logs users in through a third-party **identity/authorization provider** (Google, GitHub, Okta, Keycloak, Azure AD…). Instead of your app storing passwords, the provider authenticates the user and vouches for them. **OAuth2 vs OIDC.** OAuth2 is an *authorization* framework (delegated access to resources via tokens). OIDC (OpenID Connect) is an *authentication* layer built on top of OAuth2 that adds an **id_token** (a signed JWT describing who the user is). If the provider advertises the `openid` scope, Spring treats it as OIDC and you get an `OidcUser`; otherwise you get a plain `OAuth2User`. **The authorization-code flow, step by step:** 1. User hits a protected page; Spring redirects the browser to the provider's **authorization endpoint** with `client_id`, `redirect_uri`, `scope`, `state` (CSRF protection), and — for OIDC — a `nonce`. 2. User logs in and consents at the provider. 3. Provider redirects the browser back to Spring's default callback URI `{baseUrl}/login/oauth2/code/{registrationId}` carrying an **authorization code** and the `state`. 4. Spring (server-to-server, not through the browser) POSTs the code to the provider's **token endpoint** with the client secret to get an **access token** and, for OIDC, an **id_token**. 5. Spring calls the **userinfo endpoint** (via an `OAuth2UserService`) to fetch the user's profile, producing an `OAuth2User`/`OidcUser`. 6. Spring builds an `OAuth2AuthenticationToken` and stores it in the `SecurityContext`; the user is now authenticated. **Why authorization-code (not implicit)?** The code flow keeps tokens off the browser/URL — the sensitive token exchange happens server-side using the client secret. The `state` parameter defends against CSRF; the OIDC `nonce` binds the id_token to the session, defending against replay. **Key classes.** `OAuth2LoginAuthenticationFilter` handles the callback; `ClientRegistrationRepository` holds provider config; `OAuth2AuthorizedClientService`/`Repository` stores obtained tokens; `DefaultOAuth2UserService`/`OidcUserService` load the user. **Minimal setup.** Add `spring-boot-starter-oauth2-client`, configure `spring.security.oauth2.client.registration.<id>` (client-id, client-secret, scope) and `...provider.<id>` in properties, and call `http.oauth2Login()`. Boot even auto-configures a login page listing configured providers. **Distinguish the three OAuth2 features:** `oauth2Login()` = log users *in*; `oauth2Client()` = obtain tokens to call *downstream* APIs on the user's behalf (no login); `oauth2ResourceServer()` = *your* API validates incoming bearer JWT/opaque tokens. Confusing login with resource-server is a common mistake. **When to use.** Use `oauth2Login()` for 'Sign in with Google/GitHub/corporate SSO' in a server-rendered or session-based web app. For SPAs/mobile you often front with a dedicated auth server (BFF pattern) instead.

  • How is oauth2Login() different from oauth2ResourceServer()?
    oauth2Login() makes your app a client that logs interactive users in via redirect and creates a session/OAuth2AuthenticationToken. oauth2ResourceServer() makes your app an API that validates incoming bearer tokens (JWT or opaque) on each request — no redirect, no session, no login page.
  • What is the default callback (redirect) URI Spring registers?
    {baseUrl}/login/oauth2/code/{registrationId}, e.g. https://app.example.com/login/oauth2/code/google. This must be whitelisted at the provider as an allowed redirect URI.

saying these in an interview costs you the question

  • Saying oauth2Login() validates incoming bearer tokens (that's oauth2ResourceServer)
  • Claiming it uses the implicit flow or puts tokens in the browser URL
  • Thinking the client secret is sent through the browser rather than in the server-side token exchange
  • Believing your app stores the user's provider password

context

open as a page

What are ClientRegistration and ClientRegistrationRepository, and how does Spring populate them?

level: middleimportance: must knowfreq 60%

basics

~20 s

A ClientRegistration holds the config for one OAuth2 provider — client id/secret, scopes, and the provider's endpoint URLs. ClientRegistrationRepository is the store of all registrations, looked up by registrationId. Spring Boot builds them from your application.yml properties.

open as a page

Explain the difference between OAuth2User and OidcUser, and the role of OAuth2UserService.

level: middleimportance: must knowfreq 55%

basics

~20 s

OAuth2User is the authenticated principal for plain OAuth2 logins, exposing the provider's user attributes and granted authorities. OidcUser extends it for OIDC logins, adding access to the id_token and standard OIDC claims. OAuth2UserService loads that principal after the token exchange.

open as a page

How does Spring Security handle and validate the OIDC id_token during oauth2Login()?

level: seniorimportance: should knowfreq 45%

basics

~20 s

For OIDC logins Spring parses the id_token JWT, checks its signature against the provider's public keys (JWK set), and verifies claims like issuer, audience, expiry, and the nonce. Only if all checks pass is the OidcUser created and the user logged in.

open as a page

You need to provision local accounts and map provider claims to roles on OAuth2/OIDC login across multiple providers. How do you design this in Spring Security?

level: principalimportance: should knowfreq 35%

basics

~20 s

Plug in a custom OAuth2UserService/OidcUserService that delegates to the default, then enriches the principal: look up or just-in-time create a local account keyed by issuer+subject, and translate provider claims into GrantedAuthorities. Return a custom OAuth2User/OidcUser carrying those authorities.

open as a page