Skip to content

Commit 816ebe3

Browse files
committed
Add OpenSAML to Config Build
Issue gh-11658
1 parent 08d1be5 commit 816ebe3

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

config/spring-security-config.gradle

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ apply plugin: 'io.spring.convention.spring-module'
66
apply plugin: 'trang'
77
apply plugin: 'kotlin'
88

9+
configurations {
10+
opensaml5 {
11+
extendsFrom(optional, tests)
12+
}
13+
}
14+
915
dependencies {
1016
management platform(project(":spring-security-dependencies"))
1117
// NB: Don't add other compile time dependencies to the config module as this breaks tooling
@@ -17,7 +23,8 @@ dependencies {
1723

1824
optional project(':spring-security-ldap')
1925
optional project(':spring-security-messaging')
20-
optional project(':spring-security-saml2-service-provider')
26+
optional project(path: ':spring-security-saml2-service-provider')
27+
opensaml5 project(path: ':spring-security-saml2-service-provider', configuration: 'opensamlFiveMain')
2128
optional project(':spring-security-oauth2-client')
2229
optional project(':spring-security-oauth2-jose')
2330
optional project(':spring-security-oauth2-resource-server')
@@ -160,3 +167,15 @@ configure(project.tasks.withType(Test)) {
160167
systemProperties['springSecurityVersion'] = version
161168
}
162169
}
170+
171+
tasks.register("opensaml5Test", Test) {
172+
filter {
173+
includeTestsMatching "org.springframework.security.config.annotation.web.configurers.saml2.*"
174+
}
175+
useJUnitPlatform()
176+
classpath = sourceSets.main.output + sourceSets.test.output + configurations.opensaml5
177+
}
178+
179+
tasks.named("check") {
180+
dependsOn opensaml5Test
181+
}

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

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@
2525
import jakarta.servlet.ServletException;
2626
import jakarta.servlet.http.HttpServletRequest;
2727
import jakarta.servlet.http.HttpServletResponse;
28-
import net.shibboleth.utilities.java.support.xml.SerializeSupport;
28+
import org.instancio.internal.util.ReflectionUtils;
2929
import org.junit.jupiter.api.AfterEach;
3030
import org.junit.jupiter.api.BeforeAll;
3131
import org.junit.jupiter.api.BeforeEach;
3232
import org.junit.jupiter.api.Test;
3333
import org.junit.jupiter.api.extension.ExtendWith;
3434
import org.mockito.ArgumentCaptor;
35+
import org.opensaml.core.Version;
3536
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
3637
import org.opensaml.core.xml.io.Marshaller;
3738
import org.opensaml.saml.saml2.core.Assertion;
@@ -69,6 +70,7 @@
6970
import org.springframework.security.saml2.core.TestSaml2X509Credentials;
7071
import org.springframework.security.saml2.provider.service.authentication.AbstractSaml2AuthenticationRequest;
7172
import org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider;
73+
import org.springframework.security.saml2.provider.service.authentication.OpenSaml5AuthenticationProvider;
7274
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticatedPrincipal;
7375
import org.springframework.security.saml2.provider.service.authentication.Saml2Authentication;
7476
import org.springframework.security.saml2.provider.service.authentication.Saml2AuthenticationException;
@@ -83,6 +85,7 @@
8385
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestRepository;
8486
import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter;
8587
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
88+
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml5AuthenticationRequestResolver;
8689
import org.springframework.security.saml2.provider.service.web.authentication.Saml2AuthenticationRequestResolver;
8790
import org.springframework.security.web.FilterChainProxy;
8891
import org.springframework.security.web.SecurityFilterChain;
@@ -91,6 +94,7 @@
9194
import org.springframework.security.web.context.HttpRequestResponseHolder;
9295
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
9396
import org.springframework.security.web.context.SecurityContextRepository;
97+
import org.springframework.test.util.ReflectionTestUtils;
9498
import org.springframework.test.web.servlet.MockMvc;
9599
import org.springframework.test.web.servlet.MvcResult;
96100
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
@@ -134,6 +138,8 @@ public class Saml2LoginConfigurerTests {
134138
.verificationX509Credentials((c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
135139
.build();
136140

141+
private static final boolean USE_OPENSAML_5 = Version.getVersion().startsWith("5");
142+
137143
private static String SIGNED_RESPONSE;
138144

139145
private static final AuthenticationConverter AUTHENTICATION_CONVERTER = mock(AuthenticationConverter.class);
@@ -174,7 +180,11 @@ static void createResponse() throws Exception {
174180
registration.getSigningX509Credentials().iterator().next(), relyingPartyEntityId);
175181
Marshaller marshaller = XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(signed);
176182
Element element = marshaller.marshall(signed);
177-
String serialized = SerializeSupport.nodeToString(element);
183+
Class<?> clazz = ReflectionUtils.loadClass("net.shibboleth.utilities.java.support.xml.SerializeSupport");
184+
if (clazz == null) {
185+
clazz = ReflectionUtils.loadClass("net.shibboleth.shared.xml.SerializeSupport");
186+
}
187+
String serialized = ReflectionTestUtils.invokeMethod(clazz, "nodeToString", element);
178188
SIGNED_RESPONSE = Saml2Utils.samlEncode(serialized.getBytes(StandardCharsets.UTF_8));
179189
}
180190

@@ -541,6 +551,12 @@ Saml2AuthenticationRequestResolver authenticationRequestResolver(
541551
RelyingPartyRegistrationRepository registrations) {
542552
RelyingPartyRegistrationResolver registrationResolver = new DefaultRelyingPartyRegistrationResolver(
543553
registrations);
554+
if (USE_OPENSAML_5) {
555+
OpenSaml5AuthenticationRequestResolver delegate = new OpenSaml5AuthenticationRequestResolver(
556+
registrationResolver);
557+
delegate.setAuthnRequestCustomizer((parameters) -> parameters.getAuthnRequest().setForceAuthn(true));
558+
return delegate;
559+
}
544560
OpenSaml4AuthenticationRequestResolver delegate = new OpenSaml4AuthenticationRequestResolver(
545561
registrationResolver);
546562
delegate.setAuthnRequestCustomizer((parameters) -> parameters.getAuthnRequest().setForceAuthn(true));
@@ -574,6 +590,12 @@ Saml2AuthenticationRequestResolver authenticationRequestResolver(
574590
RelyingPartyRegistrationRepository registrations) {
575591
RelyingPartyRegistrationResolver registrationResolver = new DefaultRelyingPartyRegistrationResolver(
576592
registrations);
593+
if (USE_OPENSAML_5) {
594+
OpenSaml5AuthenticationRequestResolver delegate = new OpenSaml5AuthenticationRequestResolver(
595+
registrationResolver);
596+
delegate.setAuthnRequestCustomizer((parameters) -> parameters.getAuthnRequest().setForceAuthn(true));
597+
return delegate;
598+
}
577599
OpenSaml4AuthenticationRequestResolver delegate = new OpenSaml4AuthenticationRequestResolver(
578600
registrationResolver);
579601
delegate.setAuthnRequestCustomizer((parameters) -> parameters.getAuthnRequest().setForceAuthn(true));
@@ -752,7 +774,8 @@ Saml2AuthenticationTokenConverter authenticationTokenConverter() {
752774
@Import(Saml2LoginConfigBeans.class)
753775
static class CustomAuthenticationProviderConfig {
754776

755-
private final OpenSaml4AuthenticationProvider provider = spy(new OpenSaml4AuthenticationProvider());
777+
private final AuthenticationProvider provider = spy(
778+
USE_OPENSAML_5 ? new OpenSaml5AuthenticationProvider() : new OpenSaml4AuthenticationProvider());
756779

757780
@Bean
758781
SecurityFilterChain web(HttpSecurity http) throws Exception {

0 commit comments

Comments
 (0)