|  | @@ -15,6 +15,8 @@
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  package org.springframework.security.saml2.provider.service.authentication;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import java.io.ByteArrayInputStream;
 | 
	
		
			
				|  |  | +import java.nio.charset.StandardCharsets;
 | 
	
		
			
				|  |  |  import java.time.Duration;
 | 
	
		
			
				|  |  |  import java.time.Instant;
 | 
	
		
			
				|  |  |  import java.util.ArrayList;
 | 
	
	
		
			
				|  | @@ -32,13 +34,17 @@ import java.util.function.Function;
 | 
	
		
			
				|  |  |  import javax.annotation.Nonnull;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
 | 
	
		
			
				|  |  | +import net.shibboleth.utilities.java.support.xml.ParserPool;
 | 
	
		
			
				|  |  | +import net.shibboleth.utilities.java.support.xml.SerializeSupport;
 | 
	
		
			
				|  |  |  import org.apache.commons.logging.Log;
 | 
	
		
			
				|  |  |  import org.apache.commons.logging.LogFactory;
 | 
	
		
			
				|  |  |  import org.joda.time.DateTime;
 | 
	
		
			
				|  |  | +import org.opensaml.core.config.ConfigurationService;
 | 
	
		
			
				|  |  |  import org.opensaml.core.criterion.EntityIdCriterion;
 | 
	
		
			
				|  |  |  import org.opensaml.core.xml.XMLObject;
 | 
	
		
			
				|  |  | -import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
 | 
	
		
			
				|  |  | +import org.opensaml.core.xml.config.XMLObjectProviderRegistry;
 | 
	
		
			
				|  |  |  import org.opensaml.core.xml.io.Marshaller;
 | 
	
		
			
				|  |  | +import org.opensaml.core.xml.io.MarshallingException;
 | 
	
		
			
				|  |  |  import org.opensaml.core.xml.schema.XSAny;
 | 
	
		
			
				|  |  |  import org.opensaml.core.xml.schema.XSBoolean;
 | 
	
		
			
				|  |  |  import org.opensaml.core.xml.schema.XSBooleanValue;
 | 
	
	
		
			
				|  | @@ -65,6 +71,7 @@ import org.opensaml.saml.saml2.core.EncryptedID;
 | 
	
		
			
				|  |  |  import org.opensaml.saml.saml2.core.NameID;
 | 
	
		
			
				|  |  |  import org.opensaml.saml.saml2.core.Response;
 | 
	
		
			
				|  |  |  import org.opensaml.saml.saml2.core.SubjectConfirmation;
 | 
	
		
			
				|  |  | +import org.opensaml.saml.saml2.core.impl.ResponseUnmarshaller;
 | 
	
		
			
				|  |  |  import org.opensaml.saml.saml2.encryption.Decrypter;
 | 
	
		
			
				|  |  |  import org.opensaml.saml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver;
 | 
	
		
			
				|  |  |  import org.opensaml.saml.security.impl.SAMLSignatureProfileValidator;
 | 
	
	
		
			
				|  | @@ -88,6 +95,8 @@ import org.opensaml.xmlsec.keyinfo.impl.StaticKeyInfoCredentialResolver;
 | 
	
		
			
				|  |  |  import org.opensaml.xmlsec.signature.support.SignaturePrevalidator;
 | 
	
		
			
				|  |  |  import org.opensaml.xmlsec.signature.support.SignatureTrustEngine;
 | 
	
		
			
				|  |  |  import org.opensaml.xmlsec.signature.support.impl.ExplicitKeySignatureTrustEngine;
 | 
	
		
			
				|  |  | +import org.w3c.dom.Document;
 | 
	
		
			
				|  |  | +import org.w3c.dom.Element;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import org.springframework.core.convert.converter.Converter;
 | 
	
		
			
				|  |  |  import org.springframework.security.authentication.AbstractAuthenticationToken;
 | 
	
	
		
			
				|  | @@ -120,7 +129,6 @@ import static org.springframework.security.saml2.core.Saml2ErrorCodes.INVALID_IS
 | 
	
		
			
				|  |  |  import static org.springframework.security.saml2.core.Saml2ErrorCodes.INVALID_SIGNATURE;
 | 
	
		
			
				|  |  |  import static org.springframework.security.saml2.core.Saml2ErrorCodes.MALFORMED_RESPONSE_DATA;
 | 
	
		
			
				|  |  |  import static org.springframework.security.saml2.core.Saml2ErrorCodes.SUBJECT_NOT_FOUND;
 | 
	
		
			
				|  |  | -import static org.springframework.security.saml2.core.Saml2ErrorCodes.UNKNOWN_RESPONSE_CLASS;
 | 
	
		
			
				|  |  |  import static org.springframework.util.Assert.notNull;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
	
		
			
				|  | @@ -167,7 +175,9 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	private static Log logger = LogFactory.getLog(OpenSamlAuthenticationProvider.class);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	private final OpenSamlImplementation saml = OpenSamlImplementation.getInstance();
 | 
	
		
			
				|  |  | +	private final XMLObjectProviderRegistry registry;
 | 
	
		
			
				|  |  | +	private final ResponseUnmarshaller responseUnmarshaller;
 | 
	
		
			
				|  |  | +	private final ParserPool parserPool;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	private Converter<Assertion, Collection<? extends GrantedAuthority>> authoritiesExtractor =
 | 
	
		
			
				|  |  |  			(a -> singletonList(new SimpleGrantedAuthority("ROLE_USER")));
 | 
	
	
		
			
				|  | @@ -192,6 +202,16 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
 | 
	
		
			
				|  |  |  						this.authoritiesMapper.mapAuthorities(getAssertionAuthorities(assertion)));
 | 
	
		
			
				|  |  |  			};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	/**
 | 
	
		
			
				|  |  | +	 * Creates an {@link OpenSamlAuthenticationProvider}
 | 
	
		
			
				|  |  | +	 */
 | 
	
		
			
				|  |  | +	public OpenSamlAuthenticationProvider() {
 | 
	
		
			
				|  |  | +		this.registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
 | 
	
		
			
				|  |  | +		this.responseUnmarshaller = (ResponseUnmarshaller) this.registry.getUnmarshallerFactory()
 | 
	
		
			
				|  |  | +				.getUnmarshaller(Response.DEFAULT_ELEMENT_NAME);
 | 
	
		
			
				|  |  | +		this.parserPool = this.registry.getParserPool();
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	/**
 | 
	
		
			
				|  |  |  	 * Sets the {@link Converter} used for extracting assertion attributes that
 | 
	
		
			
				|  |  |  	 * can be mapped to authorities.
 | 
	
	
		
			
				|  | @@ -265,15 +285,13 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	private Response parse(String response) throws Saml2Exception, Saml2AuthenticationException {
 | 
	
		
			
				|  |  |  		try {
 | 
	
		
			
				|  |  | -			Object result = this.saml.resolve(response);
 | 
	
		
			
				|  |  | -			if (result instanceof Response) {
 | 
	
		
			
				|  |  | -				return (Response) result;
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			else {
 | 
	
		
			
				|  |  | -				throw authException(UNKNOWN_RESPONSE_CLASS, "Invalid response class:" + result.getClass().getName());
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -		} catch (Saml2Exception x) {
 | 
	
		
			
				|  |  | -			throw authException(MALFORMED_RESPONSE_DATA, x.getMessage(), x);
 | 
	
		
			
				|  |  | +			Document document = this.parserPool.parse(new ByteArrayInputStream(
 | 
	
		
			
				|  |  | +					response.getBytes(StandardCharsets.UTF_8)));
 | 
	
		
			
				|  |  | +			Element element = document.getDocumentElement();
 | 
	
		
			
				|  |  | +			return (Response) this.responseUnmarshaller.unmarshall(element);
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		catch (Exception e) {
 | 
	
		
			
				|  |  | +			throw authException(MALFORMED_RESPONSE_DATA, e.getMessage(), e);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -427,9 +445,14 @@ public final class OpenSamlAuthenticationProvider implements AuthenticationProvi
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	private Object getXSAnyObjectValue(XSAny xsAny) {
 | 
	
		
			
				|  |  | -		Marshaller marshaller = XMLObjectProviderRegistrySupport.getMarshallerFactory().getMarshaller(xsAny);
 | 
	
		
			
				|  |  | +		Marshaller marshaller = this.registry.getMarshallerFactory().getMarshaller(xsAny);
 | 
	
		
			
				|  |  |  		if (marshaller != null) {
 | 
	
		
			
				|  |  | -			return this.saml.serialize(xsAny);
 | 
	
		
			
				|  |  | +			try {
 | 
	
		
			
				|  |  | +				Element element = marshaller.marshall(xsAny);
 | 
	
		
			
				|  |  | +				return SerializeSupport.nodeToString(element);
 | 
	
		
			
				|  |  | +			} catch (MarshallingException e) {
 | 
	
		
			
				|  |  | +				throw new Saml2Exception(e);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		return xsAny.getTextContent();
 | 
	
		
			
				|  |  |  	}
 |