0
# OAuth2 and SAML2 Configuration
1
2
Spring Security Config provides comprehensive support for modern authentication protocols including OAuth2, OpenID Connect (OIDC), and SAML2. These configurers enable integration with external identity providers and secure API access patterns.
3
4
## OAuth2 Client Configuration
5
6
### OAuth2LoginConfigurer
7
8
Configuration for OAuth2/OpenID Connect authentication flows.
9
10
```java { .api }
11
public final class OAuth2LoginConfigurer<H extends HttpSecurityBuilder<H>>
12
extends AbstractAuthenticationFilterConfigurer<H, OAuth2LoginConfigurer<H>, OAuth2LoginAuthenticationFilter> {
13
14
// Client Registration and Repository
15
public OAuth2LoginConfigurer<H> clientRegistrationRepository(ClientRegistrationRepository clientRegistrationRepository);
16
public OAuth2LoginConfigurer<H> authorizedClientRepository(OAuth2AuthorizedClientRepository authorizedClientRepository);
17
public OAuth2LoginConfigurer<H> authorizedClientService(OAuth2AuthorizedClientService authorizedClientService);
18
19
// Login Page Configuration
20
public OAuth2LoginConfigurer<H> loginPage(String loginPage);
21
public OAuth2LoginConfigurer<H> loginProcessingUrl(String loginProcessingUrl);
22
23
// Authorization Endpoint Configuration
24
public OAuth2LoginConfigurer<H> authorizationEndpoint(Customizer<AuthorizationEndpointConfig> authorizationEndpointCustomizer);
25
26
// Redirection Endpoint Configuration
27
public OAuth2LoginConfigurer<H> redirectionEndpoint(Customizer<RedirectionEndpointConfig> redirectionEndpointCustomizer);
28
29
// Token Endpoint Configuration
30
public OAuth2LoginConfigurer<H> tokenEndpoint(Customizer<TokenEndpointConfig> tokenEndpointCustomizer);
31
32
// User Info Endpoint Configuration
33
public OAuth2LoginConfigurer<H> userInfoEndpoint(Customizer<UserInfoEndpointConfig> userInfoEndpointCustomizer);
34
35
// OIDC Logout Configuration
36
public OAuth2LoginConfigurer<H> oidcLogout(Customizer<OidcLogoutConfigurer<H>> oidcLogoutCustomizer);
37
38
// Nested Configuration Classes
39
public final class AuthorizationEndpointConfig {
40
public AuthorizationEndpointConfig baseUri(String baseUri);
41
public AuthorizationEndpointConfig authorizationRequestRepository(AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository);
42
public AuthorizationEndpointConfig authorizationRequestResolver(OAuth2AuthorizationRequestResolver authorizationRequestResolver);
43
}
44
45
public final class RedirectionEndpointConfig {
46
public RedirectionEndpointConfig baseUri(String baseUri);
47
}
48
49
public final class TokenEndpointConfig {
50
public TokenEndpointConfig accessTokenResponseClient(OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient);
51
}
52
53
public final class UserInfoEndpointConfig {
54
public UserInfoEndpointConfig userAuthoritiesMapper(GrantedAuthoritiesMapper userAuthoritiesMapper);
55
public UserInfoEndpointConfig userService(OAuth2UserService<OAuth2UserRequest, OAuth2User> oauth2UserService);
56
public UserInfoEndpointConfig oidcUserService(OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService);
57
public UserInfoEndpointConfig customUserType(Class<? extends OAuth2User> customUserType, String clientRegistrationId);
58
}
59
}
60
```
61
62
**Usage Example:**
63
64
```java
65
http.oauth2Login(oauth2 -> oauth2
66
.clientRegistrationRepository(clientRegistrationRepository())
67
.authorizedClientService(authorizedClientService())
68
.loginPage("/oauth2/authorization")
69
.authorizationEndpoint(authorization -> authorization
70
.baseUri("/oauth2/authorize")
71
.authorizationRequestRepository(cookieAuthorizationRequestRepository())
72
.authorizationRequestResolver(customAuthorizationRequestResolver())
73
)
74
.redirectionEndpoint(redirection -> redirection
75
.baseUri("/oauth2/callback/*")
76
)
77
.tokenEndpoint(token -> token
78
.accessTokenResponseClient(customAccessTokenResponseClient())
79
)
80
.userInfoEndpoint(userInfo -> userInfo
81
.userService(customOAuth2UserService())
82
.oidcUserService(customOidcUserService())
83
.userAuthoritiesMapper(customGrantedAuthoritiesMapper())
84
)
85
.successHandler(oauth2AuthenticationSuccessHandler())
86
.failureHandler(oauth2AuthenticationFailureHandler())
87
);
88
```
89
90
### OAuth2ClientConfigurer
91
92
Configuration for OAuth2 client functionality and authorized client management.
93
94
```java { .api }
95
public final class OAuth2ClientConfigurer<H extends HttpSecurityBuilder<H>>
96
extends AbstractHttpConfigurer<OAuth2ClientConfigurer<H>, H> {
97
98
// Client Registration Repository
99
public OAuth2ClientConfigurer<H> clientRegistrationRepository(ClientRegistrationRepository clientRegistrationRepository);
100
101
// Authorized Client Repository
102
public OAuth2ClientConfigurer<H> authorizedClientRepository(OAuth2AuthorizedClientRepository authorizedClientRepository);
103
104
// Authorized Client Service
105
public OAuth2ClientConfigurer<H> authorizedClientService(OAuth2AuthorizedClientService authorizedClientService);
106
107
// Authorization Code Grant Configuration
108
public OAuth2ClientConfigurer<H> authorizationCodeGrant(Customizer<AuthorizationCodeGrantConfig> authorizationCodeGrantCustomizer);
109
110
// Client Credentials Grant Configuration
111
public OAuth2ClientConfigurer<H> clientCredentialsGrant(Customizer<ClientCredentialsGrantConfig> clientCredentialsGrantCustomizer);
112
113
// Password Grant Configuration
114
public OAuth2ClientConfigurer<H> passwordGrant(Customizer<PasswordGrantConfig> passwordGrantCustomizer);
115
116
// Nested Configuration Classes
117
public final class AuthorizationCodeGrantConfig {
118
public AuthorizationCodeGrantConfig accessTokenResponseClient(OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient);
119
}
120
121
public final class ClientCredentialsGrantConfig {
122
public ClientCredentialsGrantConfig accessTokenResponseClient(OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> accessTokenResponseClient);
123
}
124
125
public final class PasswordGrantConfig {
126
public PasswordGrantConfig accessTokenResponseClient(OAuth2AccessTokenResponseClient<OAuth2PasswordGrantRequest> accessTokenResponseClient);
127
}
128
}
129
```
130
131
**Usage Example:**
132
133
```java
134
http.oauth2Client(oauth2Client -> oauth2Client
135
.clientRegistrationRepository(clientRegistrationRepository())
136
.authorizedClientRepository(authorizedClientRepository())
137
.authorizationCodeGrant(authorizationCode -> authorizationCode
138
.accessTokenResponseClient(customAuthorizationCodeTokenResponseClient())
139
)
140
.clientCredentialsGrant(clientCredentials -> clientCredentials
141
.accessTokenResponseClient(customClientCredentialsTokenResponseClient())
142
)
143
);
144
```
145
146
### OidcLogoutConfigurer
147
148
Configuration for OpenID Connect logout functionality.
149
150
```java { .api }
151
public final class OidcLogoutConfigurer<H extends HttpSecurityBuilder<H>>
152
extends AbstractHttpConfigurer<OidcLogoutConfigurer<H>, H> {
153
154
// Backchannel Logout Configuration
155
public OidcLogoutConfigurer<H> backChannel(Customizer<BackChannelLogoutConfig> backChannelCustomizer);
156
157
// RP-Initiated Logout Configuration
158
public OidcLogoutConfigurer<H> rpInitiatedLogout(Customizer<RpInitiatedLogoutConfig> rpInitiatedLogoutCustomizer);
159
160
// Nested Configuration Classes
161
public final class BackChannelLogoutConfig {
162
public BackChannelLogoutConfig logoutUri(String logoutUri);
163
}
164
165
public final class RpInitiatedLogoutConfig {
166
public RpInitiatedLogoutConfig logoutUri(String logoutUri);
167
public RpInitiatedLogoutConfig postLogoutRedirectUri(String postLogoutRedirectUri);
168
}
169
}
170
```
171
172
**Usage Example:**
173
174
```java
175
http.oidcLogout(oidcLogout -> oidcLogout
176
.backChannel(backChannel -> backChannel
177
.logoutUri("/logout/connect/back-channel")
178
)
179
.rpInitiatedLogout(rpInitiated -> rpInitiated
180
.logoutUri("/logout/connect/rp-initiated")
181
.postLogoutRedirectUri("/")
182
)
183
);
184
```
185
186
## OAuth2 Resource Server Configuration
187
188
### OAuth2ResourceServerConfigurer
189
190
Configuration for OAuth2 resource server functionality with JWT and opaque token support.
191
192
```java { .api }
193
public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<H>>
194
extends AbstractHttpConfigurer<OAuth2ResourceServerConfigurer<H>, H> {
195
196
// JWT Configuration
197
public OAuth2ResourceServerConfigurer<H> jwt(Customizer<JwtConfigurer> jwtCustomizer);
198
199
// Opaque Token Configuration
200
public OAuth2ResourceServerConfigurer<H> opaqueToken(Customizer<OpaqueTokenConfigurer> opaqueTokenCustomizer);
201
202
// Bearer Token Resolution
203
public OAuth2ResourceServerConfigurer<H> bearerTokenResolver(BearerTokenResolver bearerTokenResolver);
204
205
// Authentication Entry Point
206
public OAuth2ResourceServerConfigurer<H> authenticationEntryPoint(AuthenticationEntryPoint entryPoint);
207
208
// Access Denied Handler
209
public OAuth2ResourceServerConfigurer<H> accessDeniedHandler(AccessDeniedHandler accessDeniedHandler);
210
211
// Authentication Manager Resolver
212
public OAuth2ResourceServerConfigurer<H> authenticationManagerResolver(AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver);
213
214
// Nested Configuration Classes
215
public final class JwtConfigurer {
216
public JwtConfigurer decoder(ReactiveJwtDecoder jwtDecoder);
217
public JwtConfigurer jwkSetUri(String jwkSetUri);
218
public JwtConfigurer jwtAuthenticationConverter(Converter<Jwt, ? extends AbstractAuthenticationToken> jwtAuthenticationConverter);
219
public JwtConfigurer authenticationManager(AuthenticationManager authenticationManager);
220
}
221
222
public final class OpaqueTokenConfigurer {
223
public OpaqueTokenConfigurer introspectionUri(String introspectionUri);
224
public OpaqueTokenConfigurer introspectionClientCredentials(String clientId, String clientSecret);
225
public OpaqueTokenConfigurer introspector(OpaqueTokenIntrospector introspector);
226
public OpaqueTokenConfigurer authenticationConverter(Converter<String, ? extends AbstractAuthenticationToken> authenticationConverter);
227
public OpaqueTokenConfigurer authenticationManager(AuthenticationManager authenticationManager);
228
}
229
}
230
```
231
232
**Usage Example:**
233
234
```java
235
http.oauth2ResourceServer(oauth2 -> oauth2
236
.jwt(jwt -> jwt
237
.jwkSetUri("https://example.com/.well-known/jwks.json")
238
.jwtAuthenticationConverter(customJwtAuthenticationConverter())
239
.decoder(customJwtDecoder())
240
)
241
.bearerTokenResolver(customBearerTokenResolver())
242
.authenticationEntryPoint(customAuthenticationEntryPoint())
243
.accessDeniedHandler(customAccessDeniedHandler())
244
);
245
246
// Alternative: Opaque Token Configuration
247
http.oauth2ResourceServer(oauth2 -> oauth2
248
.opaqueToken(opaque -> opaque
249
.introspectionUri("https://example.com/oauth2/introspect")
250
.introspectionClientCredentials("client-id", "client-secret")
251
.authenticationConverter(customOpaqueTokenAuthenticationConverter())
252
)
253
);
254
```
255
256
## Common OAuth2 Provider Support
257
258
### CommonOAuth2Provider
259
260
Enum providing pre-configured OAuth2 provider settings for popular identity providers.
261
262
```java { .api }
263
public enum CommonOAuth2Provider {
264
GOOGLE {
265
@Override
266
public ClientRegistration.Builder getBuilder(String registrationId) {
267
ClientRegistration.Builder builder = getBuilder(registrationId,
268
ClientAuthenticationMethod.CLIENT_SECRET_BASIC, DEFAULT_REDIRECT_URL);
269
builder.scope("openid", "profile", "email");
270
builder.authorizationUri("https://accounts.google.com/o/oauth2/v2/auth");
271
builder.tokenUri("https://www.googleapis.com/oauth2/v4/token");
272
builder.jwkSetUri("https://www.googleapis.com/oauth2/v3/certs");
273
builder.issuerUri("https://accounts.google.com");
274
builder.userInfoUri("https://www.googleapis.com/oauth2/v3/userinfo");
275
builder.userNameAttributeName(IdTokenClaimNames.SUB);
276
builder.clientName("Google");
277
return builder;
278
}
279
},
280
281
GITHUB {
282
@Override
283
public ClientRegistration.Builder getBuilder(String registrationId) {
284
ClientRegistration.Builder builder = getBuilder(registrationId,
285
ClientAuthenticationMethod.CLIENT_SECRET_BASIC, DEFAULT_REDIRECT_URL);
286
builder.scope("read:user");
287
builder.authorizationUri("https://github.com/login/oauth/authorize");
288
builder.tokenUri("https://github.com/login/oauth/access_token");
289
builder.userInfoUri("https://api.github.com/user");
290
builder.userNameAttributeName("id");
291
builder.clientName("GitHub");
292
return builder;
293
}
294
},
295
296
FACEBOOK {
297
@Override
298
public ClientRegistration.Builder getBuilder(String registrationId) {
299
ClientRegistration.Builder builder = getBuilder(registrationId,
300
ClientAuthenticationMethod.CLIENT_SECRET_POST, DEFAULT_REDIRECT_URL);
301
builder.scope("public_profile", "email");
302
builder.authorizationUri("https://www.facebook.com/v2.8/dialog/oauth");
303
builder.tokenUri("https://graph.facebook.com/v2.8/oauth/access_token");
304
builder.userInfoUri("https://graph.facebook.com/me?fields=id,name,email");
305
builder.userNameAttributeName("id");
306
builder.clientName("Facebook");
307
return builder;
308
}
309
},
310
311
OKTA {
312
@Override
313
public ClientRegistration.Builder getBuilder(String registrationId) {
314
ClientRegistration.Builder builder = getBuilder(registrationId,
315
ClientAuthenticationMethod.CLIENT_SECRET_BASIC, DEFAULT_REDIRECT_URL);
316
builder.scope("openid", "profile", "email");
317
builder.userNameAttributeName(IdTokenClaimNames.SUB);
318
builder.clientName("Okta");
319
return builder;
320
}
321
};
322
323
private static final String DEFAULT_REDIRECT_URL = "{baseUrl}/{action}/oauth2/code/{registrationId}";
324
325
/**
326
* Create a pre-configured ClientRegistration.Builder for the provider.
327
* @param registrationId the registration identifier
328
* @return the ClientRegistration.Builder for the provider
329
*/
330
public abstract ClientRegistration.Builder getBuilder(String registrationId);
331
332
protected final ClientRegistration.Builder getBuilder(String registrationId,
333
ClientAuthenticationMethod method, String redirectUri) {
334
ClientRegistration.Builder builder = ClientRegistration.withRegistrationId(registrationId);
335
builder.clientAuthenticationMethod(method);
336
builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
337
builder.redirectUri(redirectUri);
338
return builder;
339
}
340
}
341
```
342
343
**Usage Example:**
344
345
```java
346
@Bean
347
public ClientRegistrationRepository clientRegistrationRepository() {
348
return new InMemoryClientRegistrationRepository(
349
CommonOAuth2Provider.GOOGLE.getBuilder("google")
350
.clientId("google-client-id")
351
.clientSecret("google-client-secret")
352
.build(),
353
CommonOAuth2Provider.GITHUB.getBuilder("github")
354
.clientId("github-client-id")
355
.clientSecret("github-client-secret")
356
.build()
357
);
358
}
359
```
360
361
## SAML2 Configuration
362
363
### Saml2LoginConfigurer
364
365
Configuration for SAML2 authentication flows.
366
367
```java { .api }
368
public final class Saml2LoginConfigurer<H extends HttpSecurityBuilder<H>>
369
extends AbstractAuthenticationFilterConfigurer<H, Saml2LoginConfigurer<H>, Saml2WebSsoAuthenticationFilter> {
370
371
// Relying Party Registration Repository
372
public Saml2LoginConfigurer<H> relyingPartyRegistrationRepository(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository);
373
374
// Login Processing URL
375
public Saml2LoginConfigurer<H> loginProcessingUrl(String loginProcessingUrl);
376
377
// Authentication Manager
378
public Saml2LoginConfigurer<H> authenticationManager(AuthenticationManager authenticationManager);
379
380
// Authentication Request Context Resolver
381
public Saml2LoginConfigurer<H> authenticationRequestContextResolver(Saml2AuthenticationRequestContextResolver authenticationRequestContextResolver);
382
383
// Authentication Converters
384
public Saml2LoginConfigurer<H> authenticationConverter(AuthenticationConverter authenticationConverter);
385
}
386
```
387
388
**Usage Example:**
389
390
```java
391
http.saml2Login(saml2 -> saml2
392
.relyingPartyRegistrationRepository(relyingPartyRegistrations())
393
.loginProcessingUrl("/login/saml2/sso/{registrationId}")
394
.successHandler(saml2AuthenticationSuccessHandler())
395
.failureHandler(saml2AuthenticationFailureHandler())
396
);
397
```
398
399
### Saml2LogoutConfigurer
400
401
Configuration for SAML2 logout functionality.
402
403
```java { .api }
404
public final class Saml2LogoutConfigurer<H extends HttpSecurityBuilder<H>>
405
extends AbstractHttpConfigurer<Saml2LogoutConfigurer<H>, H> {
406
407
// Relying Party Registration Repository
408
public Saml2LogoutConfigurer<H> relyingPartyRegistrationRepository(RelyingPartyRegistrationRepository relyingPartyRegistrationRepository);
409
410
// Logout Request and Response Handlers
411
public Saml2LogoutConfigurer<H> logoutRequest(Customizer<LogoutRequestConfig> logoutRequestCustomizer);
412
public Saml2LogoutConfigurer<H> logoutResponse(Customizer<LogoutResponseConfig> logoutResponseCustomizer);
413
414
// Nested Configuration Classes
415
public final class LogoutRequestConfig {
416
public LogoutRequestConfig logoutRequestResolver(Saml2LogoutRequestResolver logoutRequestResolver);
417
public LogoutRequestConfig logoutRequestSuccessHandler(Saml2LogoutRequestSuccessHandler logoutRequestSuccessHandler);
418
}
419
420
public final class LogoutResponseConfig {
421
public LogoutResponseConfig logoutResponseResolver(Saml2LogoutResponseResolver logoutResponseResolver);
422
public LogoutResponseConfig logoutResponseSuccessHandler(Saml2LogoutResponseSuccessHandler logoutResponseSuccessHandler);
423
}
424
}
425
```
426
427
**Usage Example:**
428
429
```java
430
http.saml2Logout(saml2Logout -> saml2Logout
431
.relyingPartyRegistrationRepository(relyingPartyRegistrations())
432
.logoutRequest(logoutRequest -> logoutRequest
433
.logoutRequestResolver(customSaml2LogoutRequestResolver())
434
.logoutRequestSuccessHandler(customLogoutRequestSuccessHandler())
435
)
436
.logoutResponse(logoutResponse -> logoutResponse
437
.logoutResponseResolver(customSaml2LogoutResponseResolver())
438
.logoutResponseSuccessHandler(customLogoutResponseSuccessHandler())
439
)
440
);
441
```
442
443
### Saml2MetadataConfigurer
444
445
Configuration for SAML2 metadata generation and handling.
446
447
```java { .api }
448
public final class Saml2MetadataConfigurer<H extends HttpSecurityBuilder<H>>
449
extends AbstractHttpConfigurer<Saml2MetadataConfigurer<H>, H> {
450
451
// Metadata Resolver
452
public Saml2MetadataConfigurer<H> metadataResolver(Saml2MetadataResolver metadataResolver);
453
454
// Metadata URL
455
public Saml2MetadataConfigurer<H> metadataUrl(String metadataUrl);
456
}
457
```
458
459
**Usage Example:**
460
461
```java
462
http.saml2Metadata(metadata -> metadata
463
.metadataUrl("/saml2/metadata/{registrationId}")
464
.metadataResolver(customSaml2MetadataResolver())
465
);
466
```
467
468
## Integration Patterns
469
470
### Multiple Provider Configuration
471
472
Configure multiple OAuth2 providers simultaneously:
473
474
```java
475
@Configuration
476
@EnableWebSecurity
477
public class OAuth2SecurityConfig {
478
479
@Bean
480
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
481
return http
482
.authorizeHttpRequests(authz -> authz
483
.anyRequest().authenticated()
484
)
485
.oauth2Login(oauth2 -> oauth2
486
.clientRegistrationRepository(clientRegistrationRepository())
487
.loginPage("/oauth2/authorization")
488
)
489
.oauth2Client(Customizer.withDefaults())
490
.build();
491
}
492
493
@Bean
494
public ClientRegistrationRepository clientRegistrationRepository() {
495
return new InMemoryClientRegistrationRepository(
496
googleClientRegistration(),
497
githubClientRegistration(),
498
oktaClientRegistration()
499
);
500
}
501
}
502
```
503
504
### JWT and OAuth2 Resource Server
505
506
Configure both JWT and opaque token support:
507
508
```java
509
http.oauth2ResourceServer(oauth2 -> oauth2
510
.authenticationManagerResolver(authenticationManagerResolver())
511
);
512
513
@Bean
514
public AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver() {
515
return request -> {
516
String path = request.getRequestURI();
517
if (path.startsWith("/api/v1/")) {
518
return jwtAuthenticationManager();
519
}
520
return opaqueTokenAuthenticationManager();
521
};
522
}
523
```
524
525
### Custom Token Validation
526
527
Implement custom JWT validation logic:
528
529
```java
530
http.oauth2ResourceServer(oauth2 -> oauth2
531
.jwt(jwt -> jwt
532
.decoder(customJwtDecoder())
533
.jwtAuthenticationConverter(customJwtAuthenticationConverter())
534
)
535
);
536
537
@Bean
538
public JwtDecoder customJwtDecoder() {
539
NimbusJwtDecoder decoder = NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
540
decoder.setJwtValidator(customJwtValidator());
541
return decoder;
542
}
543
```