Skip to content

Commit

Permalink
WIP: initialize OpenSAML in one class
Browse files Browse the repository at this point in the history
  • Loading branch information
strehle committed Jan 7, 2025
1 parent 5b89a27 commit a109a12
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,9 @@
package org.cloudfoundry.identity.uaa.provider.saml;

import lombok.Getter;
import net.shibboleth.utilities.java.support.xml.ParserPool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.opensaml.core.config.ConfigurationService;
import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.config.XMLObjectProviderRegistry;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
import org.opensaml.core.xml.schema.XSAny;
import org.opensaml.core.xml.schema.XSBoolean;
import org.opensaml.core.xml.schema.XSBooleanValue;
Expand Down Expand Up @@ -52,8 +48,6 @@
import org.opensaml.saml.saml2.core.StatusCode;
import org.opensaml.saml.saml2.core.SubjectConfirmation;
import org.opensaml.saml.saml2.core.SubjectConfirmationData;
import org.opensaml.saml.saml2.core.impl.AuthnRequestUnmarshaller;
import org.opensaml.saml.saml2.core.impl.ResponseUnmarshaller;
import org.opensaml.saml.security.impl.SAMLSignatureProfileValidator;
import org.opensaml.xmlsec.signature.support.SignaturePrevalidator;
import org.opensaml.xmlsec.signature.support.SignatureTrustEngine;
Expand All @@ -65,7 +59,6 @@
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.saml2.Saml2Exception;
import org.springframework.security.saml2.core.OpenSamlInitializationService;
import org.springframework.security.saml2.core.Saml2Error;
import org.springframework.security.saml2.core.Saml2ErrorCodes;
import org.springframework.security.saml2.core.Saml2ResponseValidatorResult;
Expand Down Expand Up @@ -108,23 +101,11 @@
public final class OpenSaml4AuthenticationProvider implements AuthenticationProvider {

static {
OpenSamlInitializationService.initialize();
OpenSamlXmlUtils.initialize();
}

private final Log logger = LogFactory.getLog(this.getClass());

private final ResponseUnmarshaller responseUnmarshaller;

private static final AuthnRequestUnmarshaller authnRequestUnmarshaller;

static {
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
authnRequestUnmarshaller = (AuthnRequestUnmarshaller) registry.getUnmarshallerFactory()
.getUnmarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME);
}

private final ParserPool parserPool;

private final Converter<ResponseToken, Saml2ResponseValidatorResult> responseSignatureValidator = createDefaultResponseSignatureValidator();

private final Consumer<ResponseToken> responseElementsDecrypter = createDefaultResponseElementsDecrypter();
Expand All @@ -143,10 +124,6 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
* Creates an {@link OpenSaml4AuthenticationProvider}
*/
public OpenSaml4AuthenticationProvider() {
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
this.responseUnmarshaller = (ResponseUnmarshaller) registry.getUnmarshallerFactory()
.getUnmarshaller(Response.DEFAULT_ELEMENT_NAME);
this.parserPool = registry.getParserPool();
}

/**
Expand Down Expand Up @@ -348,10 +325,10 @@ public boolean supports(Class<?> authentication) {

private Response parseResponse(String response) throws Saml2Exception, Saml2AuthenticationException {
try {
Document document = this.parserPool
Document document = OpenSamlXmlUtils.getParserPool()
.parse(new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8)));
Element element = document.getDocumentElement();
return (Response) this.responseUnmarshaller.unmarshall(element);
return (Response) OpenSamlXmlUtils.getResponseUnmarshaller().unmarshall(element);
} catch (Exception ex) {
throw createAuthenticationException(Saml2ErrorCodes.MALFORMED_RESPONSE_DATA, ex.getMessage(), ex);
}
Expand Down Expand Up @@ -621,10 +598,10 @@ private static AuthnRequest parseRequest(AbstractSaml2AuthenticationRequest requ
samlRequest = new String(Saml2Utils.samlDecode(samlRequest), StandardCharsets.UTF_8);
}
try {
Document document = XMLObjectProviderRegistrySupport.getParserPool()
Document document = OpenSamlXmlUtils.getParserPool()
.parse(new ByteArrayInputStream(samlRequest.getBytes(StandardCharsets.UTF_8)));
Element element = document.getDocumentElement();
return (AuthnRequest) authnRequestUnmarshaller.unmarshall(element);
return (AuthnRequest) OpenSamlXmlUtils.getAuthnRequestUnmarshaller().unmarshall(element);
} catch (Exception ex) {
String message = "Failed to deserialize associated authentication request [" + ex.getMessage() + "]";
throw createAuthenticationException(Saml2ErrorCodes.MALFORMED_REQUEST_DATA, message, ex);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package org.cloudfoundry.identity.uaa.provider.saml;

import lombok.extern.slf4j.Slf4j;
import net.shibboleth.utilities.java.support.xml.ParserPool;
import org.cloudfoundry.identity.uaa.provider.SamlIdentityProviderDefinition;
import org.opensaml.core.config.ConfigurationService;
import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.config.XMLObjectProviderRegistry;
import org.opensaml.core.xml.schema.XSAny;
import org.opensaml.core.xml.schema.XSBase64Binary;
import org.opensaml.core.xml.schema.XSBoolean;
Expand All @@ -12,13 +15,61 @@
import org.opensaml.core.xml.schema.XSQName;
import org.opensaml.core.xml.schema.XSString;
import org.opensaml.core.xml.schema.XSURI;
import org.opensaml.saml.saml2.core.Assertion;
import org.opensaml.saml.saml2.core.AuthnRequest;
import org.opensaml.saml.saml2.core.Response;
import org.opensaml.saml.saml2.core.impl.AssertionUnmarshaller;
import org.opensaml.saml.saml2.core.impl.AuthnRequestUnmarshaller;
import org.opensaml.saml.saml2.core.impl.ResponseUnmarshaller;
import org.springframework.security.saml2.core.OpenSamlInitializationService;

import javax.xml.namespace.QName;
import java.time.Instant;

@Slf4j
public final class OpenSamlXmlUtils {

static {
OpenSamlInitializationService.initialize();
}

static {
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
authnRequestUnmarshaller = (AuthnRequestUnmarshaller) registry.getUnmarshallerFactory()
.getUnmarshaller(AuthnRequest.DEFAULT_ELEMENT_NAME);
responseUnmarshaller = (ResponseUnmarshaller) registry.getUnmarshallerFactory()
.getUnmarshaller(Response.DEFAULT_ELEMENT_NAME);
assertionUnmarshaller = (AssertionUnmarshaller) registry.getUnmarshallerFactory()
.getUnmarshaller(Assertion.DEFAULT_ELEMENT_NAME);
parserPool = registry.getParserPool();
}

private static final ResponseUnmarshaller responseUnmarshaller;
private static final AuthnRequestUnmarshaller authnRequestUnmarshaller;
private static final AssertionUnmarshaller assertionUnmarshaller;

private static final ParserPool parserPool;

public static boolean initialize() {
return parserPool != null;
}

protected static ParserPool getParserPool() {
return parserPool;
}

protected static AuthnRequestUnmarshaller getAuthnRequestUnmarshaller() {
return authnRequestUnmarshaller;
}

protected static ResponseUnmarshaller getResponseUnmarshaller() {
return responseUnmarshaller;
}

protected static AssertionUnmarshaller getAssertionUnmarshaller() {
return assertionUnmarshaller;
}

private OpenSamlXmlUtils() {
throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.cloudfoundry.identity.uaa.provider.saml;

import lombok.extern.slf4j.Slf4j;
import net.shibboleth.utilities.java.support.xml.ParserPool;
import org.cloudfoundry.identity.uaa.authentication.BackwardsCompatibleTokenEndpointAuthenticationFilter;
import org.cloudfoundry.identity.uaa.authentication.UaaAuthentication;
import org.cloudfoundry.identity.uaa.authentication.UaaPrincipal;
Expand All @@ -31,15 +30,11 @@
import org.cloudfoundry.identity.uaa.web.UaaSavedRequestAwareAuthenticationSuccessHandler;
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.cloudfoundry.identity.uaa.zone.beans.IdentityZoneManager;
import org.opensaml.core.config.ConfigurationService;
import org.opensaml.core.xml.config.XMLObjectProviderRegistry;
import org.opensaml.saml.common.assertion.ValidationContext;
import org.opensaml.saml.saml2.assertion.SAML2AssertionValidationParameters;
import org.opensaml.saml.saml2.core.Assertion;
import org.opensaml.saml.saml2.core.Issuer;
import org.opensaml.saml.saml2.core.Response;
import org.opensaml.saml.saml2.core.impl.AssertionUnmarshaller;
import org.opensaml.saml.saml2.core.impl.ResponseUnmarshaller;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
Expand All @@ -51,7 +46,6 @@
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.saml2.Saml2Exception;
import org.springframework.security.saml2.core.OpenSamlInitializationService;
import org.springframework.security.saml2.core.Saml2Error;
import org.springframework.security.saml2.core.Saml2ErrorCodes;
import org.springframework.security.saml2.core.Saml2ResponseValidatorResult;
Expand Down Expand Up @@ -97,21 +91,7 @@ public final class Saml2BearerGrantAuthenticationConverter implements Authentica
ApplicationEventPublisherAware {

static {
OpenSamlInitializationService.initialize();
}

private static final AssertionUnmarshaller assertionUnmarshaller;
private static final ResponseUnmarshaller responseUnMarshaller;

private static final ParserPool parserPool;

static {
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
assertionUnmarshaller = (AssertionUnmarshaller) registry.getUnmarshallerFactory()
.getUnmarshaller(Assertion.DEFAULT_ELEMENT_NAME);
responseUnMarshaller = (ResponseUnmarshaller) registry.getUnmarshallerFactory()
.getUnmarshaller(Response.DEFAULT_ELEMENT_NAME);
parserPool = registry.getParserPool();
OpenSamlXmlUtils.initialize();
}

private final Converter<OpenSaml4AuthenticationProvider.AssertionToken, Saml2ResponseValidatorResult> assertionSignatureValidator = OpenSaml4AuthenticationProvider.createDefaultAssertionSignatureValidator();
Expand Down Expand Up @@ -301,21 +281,21 @@ public Authentication authenticate(Authentication authentication) throws Authent

private static Assertion parseAssertion(String assertion) throws Saml2Exception, Saml2AuthenticationException {
try {
Document document = parserPool
Document document = OpenSamlXmlUtils.getParserPool()
.parse(new ByteArrayInputStream(assertion.getBytes(StandardCharsets.UTF_8)));
Element element = document.getDocumentElement();
return (Assertion) assertionUnmarshaller.unmarshall(element);
return (Assertion) OpenSamlXmlUtils.getAssertionUnmarshaller().unmarshall(element);
} catch (Exception ex) {
throw OpenSaml4AuthenticationProvider.createAuthenticationException(Saml2ErrorCodes.INVALID_ASSERTION, "Unable to parse bearer assertion", ex);
}
}

protected static Response parseSamlResponse(String samlResponse) throws Saml2Exception, Saml2AuthenticationException {
try {
Document document = parserPool
Document document = OpenSamlXmlUtils.getParserPool()
.parse(new ByteArrayInputStream(samlResponse.getBytes(StandardCharsets.UTF_8)));
Element element = document.getDocumentElement();
return (Response) responseUnMarshaller.unmarshall(element);
return (Response) OpenSamlXmlUtils.getResponseUnmarshaller().unmarshall(element);
} catch (Exception ex) {
throw OpenSaml4AuthenticationProvider.createAuthenticationException(Saml2ErrorCodes.INVALID_RESPONSE, "Unable to parse saml response", ex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
*/
public final class Saml2Utils {


private Saml2Utils() {
throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
Expand Down

0 comments on commit a109a12

Please sign in to comment.