OAuth 2.0 and OpenID Connect: social login, Keycloak and resource servers
OAuth 2.0 is a standard for delegated authorization: an app gets a token to access resources on a user's behalf, without ever seeing the user's password. OpenID Connect (OIDC) adds authentication on top: an ID token (a JWT) that says who the user is.
The four roles: the resource owner (the user), the client (your app), the authorization server (Google, Microsoft, Okta, Keycloak, Spring Authorization Server) and the resource server (your API, which accepts the access tokens).
Which flow:
- Authorization code with PKCE: web apps, mobile apps and single-page apps. The standard choice.
- Client credentials: service-to-service calls with no user.
- Device code: TVs and CLIs.
- The old implicit and password grants are deprecated; don't use them.
In Spring Boot:
- Login with an identity provider:
spring-boot-starter-oauth2-clientplus.oauth2Login(). - An API that accepts tokens:
spring-boot-starter-oauth2-resource-serverplus anissuer-uri. Spring discovers the provider's public keys (JWKS) and validates every token. - Keycloak is a popular self-hosted authorization server: users, roles, social login and MFA without writing them yourself.
Example
@Bean
SecurityFilterChain security(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/public/**").permitAll()
.anyRequest().authenticated())
.oauth2Login(Customizer.withDefaults()) // "Log in with Google" for the web app
.build();
}
@GetMapping("/me")
Map<String, Object> me(@AuthenticationPrincipal OidcUser user) {
return Map.of(
"name", user.getFullName(), // claims from the ID token
"email", user.getEmail(),
"verified", user.getEmailVerified());
}# The web app logs users in with Google (OAuth2 client / OIDC login)
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
# The API accepts access tokens issued by Keycloak (resource server)
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://auth.javaatlas.com/realms/javaatlasCommon mistake
Treating an access token as proof of who the user is. Use the ID token (OIDC) for identity; access tokens are for calling APIs and may not even be readable by the client.
Under the hood
A resource server must check more than the signature: the issuer (iss), the audience (aud: was this token meant for this API?) and expiry. Spring checks iss and exp from the issuer-uri; add an audience validator for aud. For single-page apps, the most secure setup is a backend-for-frontend: the server does the OAuth flow and keeps tokens, and the browser only holds an HttpOnly session cookie.
Check yourself
What does PKCE protect against?
How this connects
Where this leads
You've reached the end of this thread. Try a learning path for what's next.
Was this lesson helpful?
Finished reading? Mark it complete to track your progress.