Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: initialize OpenSAML in one class #3223

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading