1
1
/*
2
- * Copyright 2002-2021 the original author or authors.
2
+ * Copyright 2002-2022 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
19
19
import java .util .LinkedHashMap ;
20
20
import java .util .Map ;
21
21
22
- import jakarta .servlet .Filter ;
23
-
24
22
import org .opensaml .core .Version ;
25
23
26
24
import org .springframework .beans .factory .NoSuchBeanDefinitionException ;
50
48
import org .springframework .security .saml2 .provider .service .web .Saml2AuthenticationRequestContextResolver ;
51
49
import org .springframework .security .saml2 .provider .service .web .Saml2AuthenticationRequestRepository ;
52
50
import org .springframework .security .saml2 .provider .service .web .Saml2AuthenticationTokenConverter ;
51
+ import org .springframework .security .saml2 .provider .service .web .authentication .Saml2AuthenticationRequestResolver ;
53
52
import org .springframework .security .web .authentication .AuthenticationConverter ;
54
53
import org .springframework .security .web .authentication .LoginUrlAuthenticationEntryPoint ;
55
54
import org .springframework .security .web .authentication .ui .DefaultLoginPageGeneratingFilter ;
@@ -115,9 +114,11 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
115
114
116
115
private String loginPage ;
117
116
118
- private String loginProcessingUrl = Saml2WebSsoAuthenticationFilter .DEFAULT_FILTER_PROCESSES_URI ;
117
+ private String authenticationRequestUri = "/saml2/authenticate/{registrationId}" ;
118
+
119
+ private Saml2AuthenticationRequestResolver authenticationRequestResolver ;
119
120
120
- private AuthenticationRequestEndpointConfig authenticationRequestEndpoint = new AuthenticationRequestEndpointConfig () ;
121
+ private String loginProcessingUrl = Saml2WebSsoAuthenticationFilter . DEFAULT_FILTER_PROCESSES_URI ;
121
122
122
123
private RelyingPartyRegistrationRepository relyingPartyRegistrationRepository ;
123
124
@@ -176,6 +177,20 @@ public Saml2LoginConfigurer<B> loginPage(String loginPage) {
176
177
return this ;
177
178
}
178
179
180
+ /**
181
+ * Use this {@link Saml2AuthenticationRequestResolver} for generating SAML 2.0
182
+ * Authentication Requests.
183
+ * @param authenticationRequestResolver
184
+ * @return the {@link Saml2LoginConfigurer} for further configuration
185
+ * @since 5.7
186
+ */
187
+ public Saml2LoginConfigurer <B > authenticationRequestResolver (
188
+ Saml2AuthenticationRequestResolver authenticationRequestResolver ) {
189
+ Assert .notNull (authenticationRequestResolver , "authenticationRequestResolver cannot be null" );
190
+ this .authenticationRequestResolver = authenticationRequestResolver ;
191
+ return this ;
192
+ }
193
+
179
194
/**
180
195
* Specifies the URL to validate the credentials. If specified a custom URL, consider
181
196
* specifying a custom {@link AuthenticationConverter} via
@@ -200,7 +215,7 @@ protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingU
200
215
201
216
/**
202
217
* {@inheritDoc}
203
- *
218
+ * <p>
204
219
* Initializes this filter chain for SAML 2 Login. The following actions are taken:
205
220
* <ul>
206
221
* <li>The WebSSO endpoint has CSRF disabled, typically {@code /login/saml2/sso}</li>
@@ -226,8 +241,8 @@ public void init(B http) throws Exception {
226
241
super .init (http );
227
242
}
228
243
else {
229
- Map <String , String > providerUrlMap = getIdentityProviderUrlMap (
230
- this .authenticationRequestEndpoint . filterProcessingUrl , this . relyingPartyRegistrationRepository );
244
+ Map <String , String > providerUrlMap = getIdentityProviderUrlMap (this . authenticationRequestUri ,
245
+ this .relyingPartyRegistrationRepository );
231
246
boolean singleProvider = providerUrlMap .size () == 1 ;
232
247
if (singleProvider ) {
233
248
// Setup auto-redirect to provider login page
@@ -247,14 +262,16 @@ public void init(B http) throws Exception {
247
262
248
263
/**
249
264
* {@inheritDoc}
250
- *
265
+ * <p>
251
266
* During the {@code configure} phase, a
252
267
* {@link Saml2WebSsoAuthenticationRequestFilter} is added to handle SAML 2.0
253
268
* AuthNRequest redirects
254
269
*/
255
270
@ Override
256
271
public void configure (B http ) throws Exception {
257
- http .addFilter (this .authenticationRequestEndpoint .build (http ));
272
+ Saml2WebSsoAuthenticationRequestFilter filter = getAuthenticationRequestFilter (http );
273
+ filter .setAuthenticationRequestRepository (getAuthenticationRequestRepository (http ));
274
+ http .addFilter (postProcess (filter ));
258
275
super .configure (http );
259
276
if (this .authenticationManager == null ) {
260
277
registerDefaultAuthenticationProvider (http );
@@ -264,6 +281,11 @@ public void configure(B http) throws Exception {
264
281
}
265
282
}
266
283
284
+ private RelyingPartyRegistrationResolver relyingPartyRegistrationResolver (B http ) {
285
+ RelyingPartyRegistrationRepository registrations = relyingPartyRegistrationRepository (http );
286
+ return new DefaultRelyingPartyRegistrationResolver (registrations );
287
+ }
288
+
267
289
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository (B http ) {
268
290
if (this .relyingPartyRegistrationRepository == null ) {
269
291
this .relyingPartyRegistrationRepository = getSharedOrBean (http , RelyingPartyRegistrationRepository .class );
@@ -276,6 +298,46 @@ private void setAuthenticationRequestRepository(B http,
276
298
saml2WebSsoAuthenticationFilter .setAuthenticationRequestRepository (getAuthenticationRequestRepository (http ));
277
299
}
278
300
301
+ private Saml2WebSsoAuthenticationRequestFilter getAuthenticationRequestFilter (B http ) {
302
+ Saml2AuthenticationRequestResolver authenticationRequestResolver = getAuthenticationRequestResolver (http );
303
+ if (authenticationRequestResolver != null ) {
304
+ return new Saml2WebSsoAuthenticationRequestFilter (authenticationRequestResolver );
305
+ }
306
+ return new Saml2WebSsoAuthenticationRequestFilter (getAuthenticationRequestContextResolver (http ),
307
+ getAuthenticationRequestFactory (http ));
308
+ }
309
+
310
+ private Saml2AuthenticationRequestResolver getAuthenticationRequestResolver (B http ) {
311
+ if (this .authenticationRequestResolver != null ) {
312
+ return this .authenticationRequestResolver ;
313
+ }
314
+ return getBeanOrNull (http , Saml2AuthenticationRequestResolver .class );
315
+ }
316
+
317
+ private Saml2AuthenticationRequestFactory getAuthenticationRequestFactory (B http ) {
318
+ Saml2AuthenticationRequestFactory resolver = getSharedOrBean (http , Saml2AuthenticationRequestFactory .class );
319
+ if (resolver != null ) {
320
+ return resolver ;
321
+ }
322
+ if (version ().startsWith ("4" )) {
323
+ return new OpenSaml4AuthenticationRequestFactory ();
324
+ }
325
+ else {
326
+ return new OpenSamlAuthenticationRequestFactory ();
327
+ }
328
+ }
329
+
330
+ private Saml2AuthenticationRequestContextResolver getAuthenticationRequestContextResolver (B http ) {
331
+ Saml2AuthenticationRequestContextResolver resolver = getBeanOrNull (http ,
332
+ Saml2AuthenticationRequestContextResolver .class );
333
+ if (resolver != null ) {
334
+ return resolver ;
335
+ }
336
+ RelyingPartyRegistrationResolver registrationResolver = new DefaultRelyingPartyRegistrationResolver (
337
+ this .relyingPartyRegistrationRepository );
338
+ return new DefaultSaml2AuthenticationRequestContextResolver (registrationResolver );
339
+ }
340
+
279
341
private AuthenticationConverter getAuthenticationConverter (B http ) {
280
342
if (this .authenticationConverter != null ) {
281
343
return this .authenticationConverter ;
@@ -325,8 +387,8 @@ private void initDefaultLoginFilter(B http) {
325
387
return ;
326
388
}
327
389
loginPageGeneratingFilter .setSaml2LoginEnabled (true );
328
- loginPageGeneratingFilter .setSaml2AuthenticationUrlToProviderName (this . getIdentityProviderUrlMap (
329
- this .authenticationRequestEndpoint . filterProcessingUrl , this .relyingPartyRegistrationRepository ));
390
+ loginPageGeneratingFilter .setSaml2AuthenticationUrlToProviderName (
391
+ this .getIdentityProviderUrlMap ( this . authenticationRequestUri , this .relyingPartyRegistrationRepository ));
330
392
loginPageGeneratingFilter .setLoginPageUrl (this .getLoginPage ());
331
393
loginPageGeneratingFilter .setFailureUrl (this .getFailureUrl ());
332
394
}
@@ -380,46 +442,4 @@ private <C> void setSharedObject(B http, Class<C> clazz, C object) {
380
442
}
381
443
}
382
444
383
- private final class AuthenticationRequestEndpointConfig {
384
-
385
- private String filterProcessingUrl = "/saml2/authenticate/{registrationId}" ;
386
-
387
- private AuthenticationRequestEndpointConfig () {
388
- }
389
-
390
- private Filter build (B http ) {
391
- Saml2AuthenticationRequestFactory authenticationRequestResolver = getResolver (http );
392
- Saml2AuthenticationRequestContextResolver contextResolver = getContextResolver (http );
393
- Saml2AuthenticationRequestRepository <AbstractSaml2AuthenticationRequest > repository = getAuthenticationRequestRepository (
394
- http );
395
- Saml2WebSsoAuthenticationRequestFilter filter = new Saml2WebSsoAuthenticationRequestFilter (contextResolver ,
396
- authenticationRequestResolver );
397
- filter .setAuthenticationRequestRepository (repository );
398
- return postProcess (filter );
399
- }
400
-
401
- private Saml2AuthenticationRequestFactory getResolver (B http ) {
402
- Saml2AuthenticationRequestFactory resolver = getSharedOrBean (http , Saml2AuthenticationRequestFactory .class );
403
- if (resolver == null ) {
404
- if (version ().startsWith ("4" )) {
405
- return new OpenSaml4AuthenticationRequestFactory ();
406
- }
407
- return new OpenSamlAuthenticationRequestFactory ();
408
- }
409
- return resolver ;
410
- }
411
-
412
- private Saml2AuthenticationRequestContextResolver getContextResolver (B http ) {
413
- Saml2AuthenticationRequestContextResolver resolver = getBeanOrNull (http ,
414
- Saml2AuthenticationRequestContextResolver .class );
415
- if (resolver == null ) {
416
- RelyingPartyRegistrationResolver relyingPartyRegistrationResolver = new DefaultRelyingPartyRegistrationResolver (
417
- Saml2LoginConfigurer .this .relyingPartyRegistrationRepository );
418
- return new DefaultSaml2AuthenticationRequestContextResolver (relyingPartyRegistrationResolver );
419
- }
420
- return resolver ;
421
- }
422
-
423
- }
424
-
425
445
}
0 commit comments