skip to content

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