SYNCOPE-1195 - Remove copy of OpenSAMLUtil when WSS4J 2.1.11 is out
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/6b3ace02 Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/6b3ace02 Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/6b3ace02 Branch: refs/heads/2_0_X Commit: 6b3ace024498e4d86bff1e12c782e6c55c036511 Parents: c8748ba Author: Colm O hEigeartaigh <cohei...@apache.org> Authored: Fri Aug 11 13:39:21 2017 +0100 Committer: Colm O hEigeartaigh <cohei...@apache.org> Committed: Fri Aug 11 13:39:21 2017 +0100 ---------------------------------------------------------------------- .../syncope/core/logic/saml2/OpenSAMLUtil.java | 141 +++++++++++++++++++ .../core/logic/saml2/SAML2ReaderWriter.java | 5 +- 2 files changed, 143 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/syncope/blob/6b3ace02/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/OpenSAMLUtil.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/OpenSAMLUtil.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/OpenSAMLUtil.java new file mode 100644 index 0000000..ff197d4 --- /dev/null +++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/OpenSAMLUtil.java @@ -0,0 +1,141 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.syncope.core.logic.saml2; + +import org.apache.wss4j.common.ext.WSSecurityException; +import org.opensaml.core.xml.XMLObject; +import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport; +import org.opensaml.core.xml.io.Marshaller; +import org.opensaml.core.xml.io.MarshallerFactory; +import org.opensaml.core.xml.io.MarshallingException; +import org.opensaml.saml.common.SignableSAMLObject; +import org.opensaml.xmlsec.signature.Signature; +import org.opensaml.xmlsec.signature.support.SignatureException; +import org.opensaml.xmlsec.signature.support.Signer; +import org.opensaml.xmlsec.signature.support.SignerProvider; +import org.w3c.dom.Document; +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.Element; + +/** + * Class OpenSAMLUtil provides static helper methods for the OpenSaml library. + * TODO Remove once we pick up WSS4J 2.1.11 - See https://issues.apache.org/jira/browse/WSS-613 + */ +final class OpenSAMLUtil { + + private OpenSAMLUtil() { + // Complete + } + + /** + * Convert a SAML Assertion from a XMLObject to a DOM Element + * + * @param xmlObject of type XMLObject + * @param doc of type Document + * @param signObject whether to sign the XMLObject during marshalling + * @return Element + * @throws WSSecurityException + */ + public static Element toDom( + final XMLObject xmlObject, + final Document doc, + final boolean signObject + ) throws WSSecurityException { + MarshallerFactory marshallerFactory = XMLObjectProviderRegistrySupport.getMarshallerFactory(); + Marshaller marshaller = marshallerFactory.getMarshaller(xmlObject); + Element element = null; + DocumentFragment frag = doc == null ? null : doc.createDocumentFragment(); + try { + if (frag != null) { + while (doc.getFirstChild() != null) { + frag.appendChild(doc.removeChild(doc.getFirstChild())); + } + } + try { + if (doc == null) { + element = marshaller.marshall(xmlObject); + } else { + element = marshaller.marshall(xmlObject, doc); + } + } catch (MarshallingException ex) { + throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, ex, "empty", + new Object[] {"Error marshalling a SAML assertion"}); + } + + if (signObject) { + signXMLObject(xmlObject); + } + } finally { + if (frag != null) { + while (doc.getFirstChild() != null) { + doc.removeChild(doc.getFirstChild()); + } + doc.appendChild(frag); + } + } + return element; + } + + private static void signXMLObject(final XMLObject xmlObject) throws WSSecurityException { + if (xmlObject instanceof org.opensaml.saml.saml1.core.Response) { + org.opensaml.saml.saml1.core.Response response = + (org.opensaml.saml.saml1.core.Response) xmlObject; + + // Sign any Assertions + if (response.getAssertions() != null) { + for (org.opensaml.saml.saml1.core.Assertion assertion : response.getAssertions()) { + signObject(assertion.getSignature()); + } + } + + signObject(response.getSignature()); + } else if (xmlObject instanceof org.opensaml.saml.saml2.core.Response) { + org.opensaml.saml.saml2.core.Response response = + (org.opensaml.saml.saml2.core.Response) xmlObject; + + // Sign any Assertions + if (response.getAssertions() != null) { + for (org.opensaml.saml.saml2.core.Assertion assertion : response.getAssertions()) { + signObject(assertion.getSignature()); + } + } + + signObject(response.getSignature()); + } else if (xmlObject instanceof SignableSAMLObject) { + signObject(((SignableSAMLObject) xmlObject).getSignature()); + } + } + + private static void signObject(final Signature signature) throws WSSecurityException { + if (signature != null) { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(SignerProvider.class.getClassLoader()); + Signer.signObject(signature); + } catch (SignatureException ex) { + throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, ex, "empty", + new Object[] {"Error signing a SAML assertion"}); + } finally { + Thread.currentThread().setContextClassLoader(loader); + } + } + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/6b3ace02/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java index f530afb..9c1bcb2 100644 --- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java +++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java @@ -49,7 +49,6 @@ import org.apache.syncope.common.lib.types.SAML2BindingType; import org.apache.syncope.core.logic.init.SAML2SPLoader; import org.apache.wss4j.common.crypto.Merlin; import org.apache.wss4j.common.ext.WSSecurityException; -import org.apache.wss4j.common.saml.OpenSAMLUtil; import org.opensaml.core.xml.XMLObject; import org.opensaml.saml.common.SignableSAMLObject; import org.opensaml.saml.saml2.core.RequestAbstractType; @@ -134,7 +133,7 @@ public class SAML2ReaderWriter { // parse the provided SAML response Document responseDoc = StaxUtils.read(new InputStreamReader(tokenStream, StandardCharsets.UTF_8)); - XMLObject responseObject = OpenSAMLUtil.fromDom(responseDoc.getDocumentElement()); + XMLObject responseObject = org.apache.wss4j.common.saml.OpenSAMLUtil.fromDom(responseDoc.getDocumentElement()); if (LOG.isDebugEnabled()) { try { @@ -152,7 +151,7 @@ public class SAML2ReaderWriter { } public void sign(final SignableSAMLObject signableObject) throws SecurityException { - org.opensaml.xmlsec.signature.Signature signature = OpenSAMLUtil.buildSignature(); + org.opensaml.xmlsec.signature.Signature signature = org.apache.wss4j.common.saml.OpenSAMLUtil.buildSignature(); signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); signature.setSignatureAlgorithm(sigAlgo); signature.setSigningCredential(loader.getCredential());