Skip to content

Commit 567c091

Browse files
Remove SAML Deprecations
Closes spring-projectsgh-11077
1 parent cfb1745 commit 567c091

File tree

39 files changed

+157
-3392
lines changed

39 files changed

+157
-3392
lines changed

config/src/main/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LoginConfigurer.java

+9-36
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,18 @@
3333
import org.springframework.security.core.Authentication;
3434
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest;
3535
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider;
36-
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationRequestFactory;
3736
import org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider;
38-
import org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationRequestFactory;
39-
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestFactory;
4037
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
4138
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
4239
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter;
4340
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationRequestFilter;
4441
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
45-
import org.springframework.security.saml2.provider.service.web.DefaultSaml2AuthenticationRequestContextResolver;
4642
import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository;
4743
import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver;
48-
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
4944
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
5045
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter;
46+
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml3AuthenticationRequestResolver;
47+
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
5148
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
5249
import org.springframework.security.web.authentication.AuthenticationConverter;
5350
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
@@ -87,7 +84,6 @@
8784
*
8885
* <ul>
8986
* <li>{@link RelyingPartyRegistrationRepository} (required)</li>
90-
* <li>{@link Saml2AuthenticationRequestFactory} (optional)</li>
9187
* </ul>
9288
*
9389
* <h2>Shared Objects Used</h2>
@@ -96,7 +92,6 @@
9692
*
9793
* <ul>
9894
* <li>{@link RelyingPartyRegistrationRepository} (required)</li>
99-
* <li>{@link Saml2AuthenticationRequestFactory} (optional)</li>
10095
* <li>{@link DefaultLoginPageGeneratingFilter} - if {@link #loginPage(String)} is not
10196
* configured and {@code DefaultLoginPageGeneratingFilter} is available, than a default
10297
* login page will be made available</li>
@@ -300,42 +295,21 @@ private void setAuthenticationRequestRepository(B http,
300295

301296
private Saml2WebSsoAuthenticationRequestFilter getAuthenticationRequestFilter(B http) {
302297
Saml2AuthenticationRequestResolver authenticationRequestResolver = getAuthenticationRequestResolver(http);
303-
if (authenticationRequestResolver != null) {
304-
return new Saml2WebSsoAuthenticationRequestFilter(authenticationRequestResolver);
305-
}
306-
return new Saml2WebSsoAuthenticationRequestFilter(getAuthenticationRequestContextResolver(http),
307-
getAuthenticationRequestFactory(http));
298+
return new Saml2WebSsoAuthenticationRequestFilter(authenticationRequestResolver);
308299
}
309300

310301
private Saml2AuthenticationRequestResolver getAuthenticationRequestResolver(B http) {
311302
if (this.authenticationRequestResolver != null) {
312303
return this.authenticationRequestResolver;
313304
}
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;
305+
Saml2AuthenticationRequestResolver bean = getBeanOrNull(http, Saml2AuthenticationRequestResolver.class);
306+
if (bean != null) {
307+
return bean;
321308
}
322309
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;
310+
return new OpenSaml4AuthenticationRequestResolver(relyingPartyRegistrationResolver(http));
335311
}
336-
RelyingPartyRegistrationResolver registrationResolver = new DefaultRelyingPartyRegistrationResolver(
337-
this.relyingPartyRegistrationRepository);
338-
return new DefaultSaml2AuthenticationRequestContextResolver(registrationResolver);
312+
return new OpenSaml3AuthenticationRequestResolver(relyingPartyRegistrationResolver(http));
339313
}
340314

341315
private AuthenticationConverter getAuthenticationConverter(B http) {
@@ -348,8 +322,7 @@ private AuthenticationConverter getAuthenticationConverter(B http) {
348322
Assert.state(this.loginProcessingUrl.contains("{registrationId}"),
349323
"loginProcessingUrl must contain {registrationId} path variable");
350324
return new Saml2AuthenticationTokenConverter(
351-
(RelyingPartyRegistrationResolver) new DefaultRelyingPartyRegistrationResolver(
352-
this.relyingPartyRegistrationRepository));
325+
new DefaultRelyingPartyRegistrationResolver(this.relyingPartyRegistrationRepository));
353326
}
354327
return authenticationConverterBean;
355328
}

config/src/test/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LoginConfigurerTests.java

-136
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.io.IOException;
2020
import java.net.URLDecoder;
2121
import java.time.Duration;
22-
import java.time.Instant;
2322
import java.util.Base64;
2423
import java.util.Collection;
2524
import java.util.Collections;
@@ -34,7 +33,6 @@
3433
import org.junit.jupiter.api.extension.ExtendWith;
3534
import org.mockito.ArgumentCaptor;
3635
import org.opensaml.saml.saml2.core.Assertion;
37-
import org.opensaml.saml.saml2.core.AuthnRequest;
3836

3937
import org.springframework.beans.factory.BeanCreationException;
4038
import org.springframework.beans.factory.annotation.Autowired;
@@ -68,23 +66,17 @@
6866
import org.springframework.security.saml2.core.TestSaml2X509Credentials;
6967
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest;
7068
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider;
71-
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationRequestFactory;
7269
import org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider;
7370
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
7471
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
7572
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
76-
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestContext;
77-
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationRequestFactory;
7873
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationToken;
79-
import org.springframework.security.saml2.provider.service.authentication.TestOpenSamlObjects;
80-
import org.springframework.security.saml2.provider.service.authentication.TestSaml2AuthenticationRequestContexts;
8174
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
8275
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
8376
import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations;
8477
import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter;
8578
import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver;
8679
import org.springframework.security.saml2.provider.service.web.RelyingPartyRegistrationResolver;
87-
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
8880
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
8981
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter;
9082
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
@@ -113,7 +105,6 @@
113105
import static org.mockito.BDDMockito.given;
114106
import static org.mockito.Mockito.mock;
115107
import static org.mockito.Mockito.verify;
116-
import static org.mockito.Mockito.verifyNoInteractions;
117108
import static org.springframework.security.config.Customizer.withDefaults;
118109
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
119110
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@@ -211,30 +202,6 @@ public void saml2LoginWhenConfiguringAuthenticationDefaultsUsingCustomizerThenTh
211202
validateSaml2WebSsoAuthenticationFilterConfiguration();
212203
}
213204

214-
@Test
215-
public void saml2LoginWhenCustomAuthenticationRequestContextResolverThenUses() throws Exception {
216-
this.spring.register(CustomAuthenticationRequestContextResolver.class).autowire();
217-
Saml2AuthenticationRequestContext context = TestSaml2AuthenticationRequestContexts
218-
.authenticationRequestContext().build();
219-
Saml2AuthenticationRequestContextResolver resolver = this.spring.getContext()
220-
.getBean(Saml2AuthenticationRequestContextResolver.class);
221-
given(resolver.resolve(any(HttpServletRequest.class))).willReturn(context);
222-
this.mvc.perform(get("/saml2/authenticate/registration-id")).andExpect(status().isFound());
223-
verify(resolver).resolve(any(HttpServletRequest.class));
224-
}
225-
226-
@Test
227-
public void authenticationRequestWhenAuthnRequestContextConverterThenUses() throws Exception {
228-
this.spring.register(CustomAuthenticationRequestContextConverterResolver.class).autowire();
229-
230-
MvcResult result = this.mvc.perform(get("/saml2/authenticate/registration-id")).andReturn();
231-
UriComponents components = UriComponentsBuilder.fromHttpUrl(result.getResponse().getRedirectedUrl()).build();
232-
String samlRequest = components.getQueryParams().getFirst("SAMLRequest");
233-
String decoded = URLDecoder.decode(samlRequest, "UTF-8");
234-
String inflated = Saml2Utils.samlInflate(Saml2Utils.samlDecode(decoded));
235-
assertThat(inflated).contains("ForceAuthn=\"true\"");
236-
}
237-
238205
@Test
239206
public void authenticationRequestWhenAuthenticationRequestResolverBeanThenUses() throws Exception {
240207
this.spring.register(CustomAuthenticationRequestResolverBean.class).autowire();
@@ -257,19 +224,6 @@ public void authenticationRequestWhenAuthenticationRequestResolverDslThenUses()
257224
assertThat(inflated).contains("ForceAuthn=\"true\"");
258225
}
259226

260-
@Test
261-
public void authenticationRequestWhenAuthenticationRequestResolverAndFactoryThenResolverTakesPrecedence()
262-
throws Exception {
263-
this.spring.register(CustomAuthenticationRequestResolverPrecedence.class).autowire();
264-
MvcResult result = this.mvc.perform(get("/saml2/authenticate/registration-id")).andReturn();
265-
UriComponents components = UriComponentsBuilder.fromHttpUrl(result.getResponse().getRedirectedUrl()).build();
266-
String samlRequest = components.getQueryParams().getFirst("SAMLRequest");
267-
String decoded = URLDecoder.decode(samlRequest, "UTF-8");
268-
String inflated = Saml2Utils.samlInflate(Saml2Utils.samlDecode(decoded));
269-
assertThat(inflated).contains("ForceAuthn=\"true\"");
270-
verifyNoInteractions(this.spring.getContext().getBean(Saml2AuthenticationRequestFactory.class));
271-
}
272-
273227
@Test
274228
public void authenticateWhenCustomAuthenticationConverterThenUses() throws Exception {
275229
this.spring.register(CustomAuthenticationConverter.class).autowire();
@@ -513,61 +467,6 @@ protected void configure(HttpSecurity http) throws Exception {
513467

514468
}
515469

516-
@EnableWebSecurity
517-
@Import(Saml2LoginConfigBeans.class)
518-
static class CustomAuthenticationRequestContextResolver extends WebSecurityConfigurerAdapter {
519-
520-
private final Saml2AuthenticationRequestContextResolver resolver = mock(
521-
Saml2AuthenticationRequestContextResolver.class);
522-
523-
@Override
524-
protected void configure(HttpSecurity http) throws Exception {
525-
// @formatter:off
526-
http
527-
.authorizeRequests((authz) -> authz
528-
.anyRequest().authenticated()
529-
)
530-
.saml2Login(withDefaults());
531-
// @formatter:on
532-
}
533-
534-
@Bean
535-
Saml2AuthenticationRequestContextResolver resolver() {
536-
return this.resolver;
537-
}
538-
539-
}
540-
541-
@EnableWebSecurity
542-
@Import(Saml2LoginConfigBeans.class)
543-
static class CustomAuthenticationRequestContextConverterResolver extends WebSecurityConfigurerAdapter {
544-
545-
@Override
546-
protected void configure(HttpSecurity http) throws Exception {
547-
// @formatter:off
548-
http
549-
.authorizeRequests((authz) -> authz
550-
.anyRequest().authenticated()
551-
)
552-
.saml2Login((saml2) -> {
553-
});
554-
// @formatter:on
555-
}
556-
557-
@Bean
558-
Saml2AuthenticationRequestFactory authenticationRequestFactory() {
559-
OpenSaml4AuthenticationRequestFactory authenticationRequestFactory = new OpenSaml4AuthenticationRequestFactory();
560-
authenticationRequestFactory.setAuthenticationRequestContextConverter((context) -> {
561-
AuthnRequest authnRequest = TestOpenSamlObjects.authnRequest();
562-
authnRequest.setIssueInstant(Instant.now());
563-
authnRequest.setForceAuthn(true);
564-
return authnRequest;
565-
});
566-
return authenticationRequestFactory;
567-
}
568-
569-
}
570-
571470
@EnableWebSecurity
572471
@Import(Saml2LoginConfigBeans.class)
573472
static class CustomAuthenticationRequestResolverBean {
@@ -630,41 +529,6 @@ Saml2AuthenticationRequestResolver authenticationRequestResolver(
630529

631530
}
632531

633-
@EnableWebSecurity
634-
@Import(Saml2LoginConfigBeans.class)
635-
static class CustomAuthenticationRequestResolverPrecedence {
636-
637-
@Bean
638-
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
639-
// @formatter:off
640-
http
641-
.authorizeRequests((authz) -> authz
642-
.anyRequest().authenticated()
643-
)
644-
.saml2Login(Customizer.withDefaults());
645-
// @formatter:on
646-
647-
return http.build();
648-
}
649-
650-
@Bean
651-
Saml2AuthenticationRequestFactory authenticationRequestFactory() {
652-
return mock(Saml2AuthenticationRequestFactory.class);
653-
}
654-
655-
@Bean
656-
Saml2AuthenticationRequestResolver authenticationRequestResolver(
657-
RelyingPartyRegistrationRepository registrations) {
658-
RelyingPartyRegistrationResolver registrationResolver = new DefaultRelyingPartyRegistrationResolver(
659-
registrations);
660-
OpenSaml4AuthenticationRequestResolver delegate = new OpenSaml4AuthenticationRequestResolver(
661-
registrationResolver);
662-
delegate.setAuthnRequestCustomizer((parameters) -> parameters.getAuthnRequest().setForceAuthn(true));
663-
return delegate;
664-
}
665-
666-
}
667-
668532
@EnableWebSecurity
669533
@Import(Saml2LoginConfigBeans.class)
670534
static class CustomAuthenticationConverter extends WebSecurityConfigurerAdapter {

config/src/test/java/org/springframework/security/config/annotation/web/configurers/saml2/TestSaml2Credentials.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,8 +23,7 @@
2323
import java.security.cert.X509Certificate;
2424

2525
import org.springframework.security.converter.RsaKeyConverters;
26-
import org.springframework.security.saml2.credentials.Saml2X509Credential;
27-
import org.springframework.security.saml2.credentials.Saml2X509Credential.Saml2X509CredentialType;
26+
import org.springframework.security.saml2.core.Saml2X509Credential;
2827

2928
/**
3029
* Preconfigured SAML credentials for SAML integration tests.
@@ -61,7 +60,8 @@ static Saml2X509Credential verificationCertificate() {
6160
+ "lx13Y1YlQ4/tlpgTgfIJxKV6nyPiLoK0nywbMd+vpAirDt2Oc+hk\n"
6261
+ "-----END CERTIFICATE-----";
6362
// @formatter:on
64-
return new Saml2X509Credential(x509Certificate(certificate), Saml2X509CredentialType.VERIFICATION);
63+
return new Saml2X509Credential(x509Certificate(certificate),
64+
Saml2X509Credential.Saml2X509CredentialType.VERIFICATION);
6565
}
6666

6767
static X509Certificate x509Certificate(String source) {
@@ -114,7 +114,8 @@ static Saml2X509Credential signingCredential() {
114114
// @formatter:on
115115
PrivateKey pk = RsaKeyConverters.pkcs8().convert(new ByteArrayInputStream(key.getBytes()));
116116
X509Certificate cert = x509Certificate(certificate);
117-
return new Saml2X509Credential(pk, cert, Saml2X509CredentialType.SIGNING, Saml2X509CredentialType.DECRYPTION);
117+
return new Saml2X509Credential(pk, cert, Saml2X509Credential.Saml2X509CredentialType.SIGNING,
118+
Saml2X509Credential.Saml2X509CredentialType.DECRYPTION);
118119
}
119120

120121
}

config/src/test/java/org/springframework/security/config/http/Saml2LoginBeanDefinitionParserTests.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
4141
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationToken;
4242
import org.springframework.security.saml2.provider.service.authentication.Saml2RedirectAuthenticationRequest;
43-
import org.springframework.security.saml2.provider.service.authentication.TestSaml2AuthenticationRequestContexts;
4443
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
4544
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
4645
import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations;
@@ -231,8 +230,7 @@ public void authenticationRequestWhenCustomAuthenticationRequestContextResolverT
231230
.configLocations(this.xml("WithCustomRelyingPartyRepository-WithCustomAuthenticationRequestResolver"))
232231
.autowire();
233232
Saml2RedirectAuthenticationRequest request = Saml2RedirectAuthenticationRequest
234-
.withAuthenticationRequestContext(
235-
TestSaml2AuthenticationRequestContexts.authenticationRequestContext().build())
233+
.withRelyingPartyRegistration(TestRelyingPartyRegistrations.noCredentials().build())
236234
.samlRequest("request").authenticationRequestUri(IDP_SSO_URL).build();
237235
given(this.authenticationRequestResolver.resolve(any(HttpServletRequest.class))).willReturn(request);
238236
this.mvc.perform(get("/saml2/authenticate/registration-id")).andExpect(status().isFound());

0 commit comments

Comments
 (0)