From fc007aa373c7de18dfbdd2440b892e91c193ee06 Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Mon, 18 Dec 2023 11:34:14 -0700 Subject: [PATCH] Check OpenSAML Version in XML Support Closes gh-12483 --- .../Saml2LoginBeanDefinitionParserUtils.java | 37 +++++++++++++++++-- .../Saml2LogoutBeanDefinitionParserUtils.java | 35 ++++++++++++++++-- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/config/src/main/java/org/springframework/security/config/http/Saml2LoginBeanDefinitionParserUtils.java b/config/src/main/java/org/springframework/security/config/http/Saml2LoginBeanDefinitionParserUtils.java index 530aba60f87..cfca5fce18c 100644 --- a/config/src/main/java/org/springframework/security/config/http/Saml2LoginBeanDefinitionParserUtils.java +++ b/config/src/main/java/org/springframework/security/config/http/Saml2LoginBeanDefinitionParserUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.security.config.http; +import org.opensaml.core.Version; import org.w3c.dom.Element; import org.springframework.beans.BeanMetadataElement; @@ -27,6 +28,7 @@ import org.springframework.security.saml2.provider.service.web.DefaultRelyingPartyRegistrationResolver; import org.springframework.security.saml2.provider.service.web.HttpSessionSaml2AuthenticationRequestRepository; import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter; +import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; /** @@ -35,6 +37,8 @@ */ final class Saml2LoginBeanDefinitionParserUtils { + private static final String OPEN_SAML_4_VERSION = "4"; + private static final String ATT_RELYING_PARTY_REGISTRATION_REPOSITORY_REF = "relying-party-registration-repository-ref"; private static final String ATT_AUTHENTICATION_REQUEST_REPOSITORY_REF = "authentication-request-repository-ref"; @@ -78,15 +82,27 @@ static BeanMetadataElement createDefaultAuthenticationRequestResolver( .rootBeanDefinition(DefaultRelyingPartyRegistrationResolver.class) .addConstructorArgValue(relyingPartyRegistrationRepository) .getBeanDefinition(); + if (version().startsWith("4")) { + return BeanDefinitionBuilder.rootBeanDefinition( + "org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver") + .addConstructorArgValue(defaultRelyingPartyRegistrationResolver) + .getBeanDefinition(); + } return BeanDefinitionBuilder.rootBeanDefinition( - "org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver") + "org.springframework.security.saml2.provider.service.web.authentication.OpenSamlAuthenticationRequestResolver") .addConstructorArgValue(defaultRelyingPartyRegistrationResolver) .getBeanDefinition(); } static BeanDefinition createAuthenticationProvider() { - return BeanDefinitionBuilder.rootBeanDefinition( - "org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider") + if (version().startsWith("4")) { + return BeanDefinitionBuilder.rootBeanDefinition( + "org.springframework.security.saml2.provider.service.authentication.OpenSaml4AuthenticationProvider") + .getBeanDefinition(); + } + return BeanDefinitionBuilder + .rootBeanDefinition( + "org.springframework.security.saml2.provider.service.authentication.OpenSamlAuthenticationProvider") .getBeanDefinition(); } @@ -108,4 +124,17 @@ static BeanDefinition createDefaultAuthenticationConverter(BeanMetadataElement r .getBeanDefinition(); } + static String version() { + String version = Version.getVersion(); + if (StringUtils.hasText(version)) { + return version; + } + boolean openSaml4ClassPresent = ClassUtils + .isPresent("org.opensaml.core.xml.persist.impl.PassthroughSourceStrategy", null); + if (openSaml4ClassPresent) { + return OPEN_SAML_4_VERSION; + } + throw new IllegalStateException("cannot determine OpenSAML version"); + } + } diff --git a/config/src/main/java/org/springframework/security/config/http/Saml2LogoutBeanDefinitionParserUtils.java b/config/src/main/java/org/springframework/security/config/http/Saml2LogoutBeanDefinitionParserUtils.java index c7cb1792d59..433c73ba600 100644 --- a/config/src/main/java/org/springframework/security/config/http/Saml2LogoutBeanDefinitionParserUtils.java +++ b/config/src/main/java/org/springframework/security/config/http/Saml2LogoutBeanDefinitionParserUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.security.config.http; +import org.opensaml.core.Version; import org.w3c.dom.Element; import org.springframework.beans.BeanMetadataElement; @@ -25,6 +26,7 @@ import org.springframework.security.saml2.provider.service.authentication.logout.OpenSamlLogoutResponseValidator; import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository; import org.springframework.security.saml2.provider.service.web.authentication.logout.HttpSessionLogoutRequestRepository; +import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; /** @@ -33,6 +35,8 @@ */ final class Saml2LogoutBeanDefinitionParserUtils { + private static final String OPEN_SAML_4_VERSION = "4"; + private static final String ATT_RELYING_PARTY_REGISTRATION_REPOSITORY_REF = "relying-party-registration-repository-ref"; private static final String ATT_LOGOUT_REQUEST_VALIDATOR_REF = "logout-request-validator-ref"; @@ -62,8 +66,14 @@ static BeanMetadataElement getLogoutResponseResolver(Element element, BeanMetada if (StringUtils.hasText(logoutResponseResolver)) { return new RuntimeBeanReference(logoutResponseResolver); } + if (version().startsWith("4")) { + return BeanDefinitionBuilder.rootBeanDefinition( + "org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSaml4LogoutResponseResolver") + .addConstructorArgValue(registrations) + .getBeanDefinition(); + } return BeanDefinitionBuilder.rootBeanDefinition( - "org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSaml4LogoutResponseResolver") + "org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSamlLogoutResponseResolver") .addConstructorArgValue(registrations) .getBeanDefinition(); } @@ -97,10 +107,29 @@ static BeanMetadataElement getLogoutRequestResolver(Element element, BeanMetadat if (StringUtils.hasText(logoutRequestResolver)) { return new RuntimeBeanReference(logoutRequestResolver); } + if (version().startsWith("4")) { + return BeanDefinitionBuilder.rootBeanDefinition( + "org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSaml4LogoutRequestResolver") + .addConstructorArgValue(registrations) + .getBeanDefinition(); + } return BeanDefinitionBuilder.rootBeanDefinition( - "org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSaml4LogoutRequestResolver") + "org.springframework.security.saml2.provider.service.web.authentication.logout.OpenSamlLogoutRequestResolver") .addConstructorArgValue(registrations) .getBeanDefinition(); } + static String version() { + String version = Version.getVersion(); + if (StringUtils.hasText(version)) { + return version; + } + boolean openSaml4ClassPresent = ClassUtils + .isPresent("org.opensaml.core.xml.persist.impl.PassthroughSourceStrategy", null); + if (openSaml4ClassPresent) { + return OPEN_SAML_4_VERSION; + } + throw new IllegalStateException("cannot determine OpenSAML version"); + } + }