You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by bu...@apache.org on 2021/02/19 10:50:58 UTC

[cxf-fediz] 01/02: fediz-core: extract duplicate code in SAMLProcessorImpl

This is an automated email from the ASF dual-hosted git repository.

buhhunyx pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf-fediz.git

commit 92c3fad474c18fe721ae7937c480e28033dbb154
Author: Alexey Markevich <bu...@gmail.com>
AuthorDate: Fri Feb 19 13:49:59 2021 +0300

    fediz-core: extract duplicate code in SAMLProcessorImpl
---
 .../fediz/core/processor/SAMLProcessorImpl.java    | 110 ++++++++-------------
 .../core/samlsso/SAMLEncryptedResponseTest.java    |  67 ++++---------
 2 files changed, 62 insertions(+), 115 deletions(-)

diff --git a/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java b/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java
index 8269aa8..78a8056 100644
--- a/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java
+++ b/plugins/core/src/main/java/org/apache/cxf/fediz/core/processor/SAMLProcessorImpl.java
@@ -77,7 +77,6 @@ import org.opensaml.saml.saml2.encryption.Decrypter;
 import org.opensaml.saml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver;
 import org.opensaml.security.x509.BasicX509Credential;
 import org.opensaml.xmlsec.encryption.support.ChainingEncryptedKeyResolver;
-import org.opensaml.xmlsec.encryption.support.EncryptedKeyResolver;
 import org.opensaml.xmlsec.encryption.support.InlineEncryptedKeyResolver;
 import org.opensaml.xmlsec.encryption.support.SimpleKeyInfoReferenceEncryptedKeyResolver;
 import org.opensaml.xmlsec.encryption.support.SimpleRetrievalMethodEncryptedKeyResolver;
@@ -149,43 +148,12 @@ public class SAMLProcessorImpl extends AbstractFedizProcessor {
         RequestState requestState =
             processRelayState(request.getState(), request.getRequestState(), config);
 
-        InputStream tokenStream = null;
-        try {
-            byte[] deflatedToken = Base64.getDecoder().decode(request.getResponseToken());
-            if (protocol.isDisableDeflateEncoding()) {
-                tokenStream = new ByteArrayInputStream(deflatedToken);
-            } else {
-                tokenStream = CompressionUtils.inflate(deflatedToken);
-            }
-        } catch (IllegalArgumentException | DataFormatException ex) {
-            LOG.warn("Invalid data format", ex);
-            throw new ProcessingException(TYPE.INVALID_REQUEST);
-        }
-
-        Document doc = null;
-        Element el = null;
-        try {
-            doc = DOMUtils.readXml(tokenStream);
-            el = doc.getDocumentElement();
-
-        } catch (Exception e) {
-            LOG.warn("Failed to parse token", e);
-            throw new ProcessingException(TYPE.INVALID_REQUEST);
-        }
-
-        LOG.debug("Received response: " + DOM2Writer.nodeToString(el));
-
-        XMLObject responseObject = null;
-        try {
-            responseObject = OpenSAMLUtil.fromDom(el);
-        } catch (WSSecurityException ex) {
-            LOG.debug(ex.getMessage(), ex);
-            throw new ProcessingException(TYPE.INVALID_REQUEST);
-        }
+        final XMLObject responseObject = getXMLObjectFromToken(request.getResponseToken(),
+            protocol.isDisableDeflateEncoding());
         if (!(responseObject instanceof org.opensaml.saml.saml2.core.Response)) {
             throw new ProcessingException(TYPE.INVALID_REQUEST);
         }
-        
+
         // Decrypt encrypted assertions
         decryptEncryptedAssertions((org.opensaml.saml.saml2.core.Response) responseObject, config);
 
@@ -309,7 +277,7 @@ public class SAMLProcessorImpl extends AbstractFedizProcessor {
                 StaticKeyInfoCredentialResolver resolver = new StaticKeyInfoCredentialResolver(cred);
                 
                 ChainingEncryptedKeyResolver keyResolver = new ChainingEncryptedKeyResolver(
-                        Arrays.<EncryptedKeyResolver>asList(
+                        Arrays.asList(
                                 new InlineEncryptedKeyResolver(),
                                 new EncryptedElementTypeEncryptedKeyResolver(), 
                                 new SimpleRetrievalMethodEncryptedKeyResolver(),
@@ -339,39 +307,8 @@ public class SAMLProcessorImpl extends AbstractFedizProcessor {
     private FedizResponse processSignOutResponse(FedizRequest request, FedizContext config) throws ProcessingException {
         SAMLProtocol protocol = (SAMLProtocol)config.getProtocol();
 
-        InputStream tokenStream = null;
-        try {
-            byte[] deflatedToken = Base64.getDecoder().decode(request.getResponseToken());
-            if (protocol.isDisableDeflateEncoding()) {
-                tokenStream = new ByteArrayInputStream(deflatedToken);
-            } else {
-                tokenStream = CompressionUtils.inflate(deflatedToken);
-            }
-        } catch (IllegalArgumentException | DataFormatException ex) {
-            LOG.warn("Invalid data format", ex);
-            throw new ProcessingException(TYPE.INVALID_REQUEST);
-        }
-
-        Document doc = null;
-        Element el = null;
-        try {
-            doc = DOMUtils.readXml(tokenStream);
-            el = doc.getDocumentElement();
-
-        } catch (Exception e) {
-            LOG.warn("Failed to parse token", e);
-            throw new ProcessingException(TYPE.INVALID_REQUEST);
-        }
-
-        LOG.debug("Received response: " + DOM2Writer.nodeToString(el));
-
-        XMLObject responseObject = null;
-        try {
-            responseObject = OpenSAMLUtil.fromDom(el);
-        } catch (WSSecurityException ex) {
-            LOG.debug(ex.getMessage(), ex);
-            throw new ProcessingException(TYPE.INVALID_REQUEST);
-        }
+        final XMLObject responseObject = getXMLObjectFromToken(request.getResponseToken(),
+            protocol.isDisableDeflateEncoding());
         if (!(responseObject instanceof org.opensaml.saml.saml2.core.LogoutResponse)) {
             throw new ProcessingException(TYPE.INVALID_REQUEST);
         }
@@ -402,6 +339,41 @@ public class SAMLProcessorImpl extends AbstractFedizProcessor {
         return fedResponse;
     }
 
+    private static XMLObject getXMLObjectFromToken(String token, boolean isDisableDeflateEncoding)
+        throws ProcessingException {
+        final InputStream tokenStream;
+        try {
+            byte[] deflatedToken = Base64.getDecoder().decode(token);
+            if (isDisableDeflateEncoding) {
+                tokenStream = new ByteArrayInputStream(deflatedToken);
+            } else {
+                tokenStream = CompressionUtils.inflate(deflatedToken);
+            }
+        } catch (IllegalArgumentException | DataFormatException ex) {
+            LOG.warn("Invalid data format", ex);
+            throw new ProcessingException(TYPE.INVALID_REQUEST);
+        }
+
+        final Element el;
+        try (InputStream is = tokenStream) {
+            el = DOMUtils.readXml(is).getDocumentElement();
+        } catch (Exception e) {
+            LOG.warn("Failed to parse token", e);
+            throw new ProcessingException(TYPE.INVALID_REQUEST);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Received response: " + DOM2Writer.nodeToString(el));
+        }
+
+        try {
+            return OpenSAMLUtil.fromDom(el);
+        } catch (WSSecurityException ex) {
+            LOG.debug(ex.getMessage(), ex);
+            throw new ProcessingException(TYPE.INVALID_REQUEST);
+        }
+    }
+
     /**
      * Validate the received SAML Response as per the protocol
      * @throws ProcessingException
diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLEncryptedResponseTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLEncryptedResponseTest.java
index 2c2b20a..09dd547 100644
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLEncryptedResponseTest.java
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLEncryptedResponseTest.java
@@ -19,10 +19,10 @@
 
 package org.apache.cxf.fediz.core.samlsso;
 
-import java.io.File;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
 import java.net.URI;
-import java.net.URL;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.security.Key;
@@ -37,8 +37,6 @@ import javax.crypto.SecretKey;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.servlet.http.HttpServletRequest;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -57,6 +55,7 @@ import org.apache.cxf.fediz.core.processor.FedizProcessor;
 import org.apache.cxf.fediz.core.processor.FedizRequest;
 import org.apache.cxf.fediz.core.processor.FedizResponse;
 import org.apache.cxf.fediz.core.processor.SAMLProcessorImpl;
+import org.apache.cxf.fediz.core.util.DOMUtils;
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.crypto.CryptoFactory;
 import org.apache.wss4j.common.crypto.CryptoType;
@@ -99,31 +98,22 @@ public class SAMLEncryptedResponseTest {
     static final String TEST_IDP_ISSUER = "http://url_to_the_issuer";
     static final String TEST_CLIENT_ADDRESS = "https://127.0.0.1";
 
-    private static final String CONFIG_FILE = "fediz_test_config_saml.xml";
+    private static final String CONFIG_FILE = "/fediz_test_config_saml.xml";
 
     private static Crypto crypto;
     private static CallbackHandler cbPasswordHandler;
     private static FedizConfigurator configurator;
-    private static DocumentBuilderFactory docBuilderFactory;
 
     static {
         OpenSAMLUtil.initSamlEngine();
-        docBuilderFactory = DocumentBuilderFactory.newInstance();
-        docBuilderFactory.setNamespaceAware(true);
     }
 
 
     @BeforeClass
-    public static void init() {
-        try {
-            crypto = CryptoFactory.getInstance("signature.properties");
-            cbPasswordHandler = new KeystoreCallbackHandler();
-            getFederationConfigurator();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        Assert.assertNotNull(configurator);
-
+    public static void init() throws Exception {
+        crypto = CryptoFactory.getInstance("signature.properties");
+        cbPasswordHandler = new KeystoreCallbackHandler();
+        getFederationConfigurator();
     }
 
     @AfterClass
@@ -132,21 +122,14 @@ public class SAMLEncryptedResponseTest {
     }
 
 
-    private static FedizConfigurator getFederationConfigurator() {
-        if (configurator != null) {
-            return configurator;
-        }
-        try {
-            configurator = new FedizConfigurator();
-            final URL resource = Thread.currentThread().getContextClassLoader()
-                    .getResource(CONFIG_FILE);
-            File f = new File(resource.toURI());
-            configurator.loadConfig(f);
-            return configurator;
-        } catch (Exception e) {
-            e.printStackTrace();
-            return null;
+    private static FedizConfigurator getFederationConfigurator() throws Exception {
+        if (configurator == null) {
+            try (Reader r = new InputStreamReader(SAMLEncryptedResponseTest.class.getResourceAsStream(CONFIG_FILE))) {
+                configurator = new FedizConfigurator();
+                configurator.loadConfig(r);
+            }
         }
+        return configurator;
     }
 
     @org.junit.Test
@@ -346,7 +329,7 @@ public class SAMLEncryptedResponseTest {
         }
     }
 
-    private String createSamlResponseStr(AbstractSAMLCallbackHandler saml2CallbackHandler,
+    private static String createSamlResponseStr(AbstractSAMLCallbackHandler saml2CallbackHandler,
                                          String requestId,
                                          boolean signAssertion) throws Exception {
         ConditionsBean cp = new ConditionsBean();
@@ -371,7 +354,7 @@ public class SAMLEncryptedResponseTest {
         return encodeResponse(response);
     }
 
-    private Element createEncryptedSamlResponse(SamlAssertionWrapper assertion, String alias,
+    private static Element createEncryptedSamlResponse(SamlAssertionWrapper assertion, String alias,
                                        boolean sign, String requestID)
             throws IOException, UnsupportedCallbackException, WSSecurityException, Exception {
         WSPasswordCallback[] cb = {new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE)};
@@ -382,8 +365,6 @@ public class SAMLEncryptedResponseTest {
             assertion.signAssertion(alias, password, crypto, false);
         }
 
-        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
-
         Status status =
                 SAML2PResponseComponentBuilder.createStatus(
                         "urn:oasis:names:tc:SAML:2.0:status:Success", null
@@ -393,7 +374,7 @@ public class SAMLEncryptedResponseTest {
                         assertion.getIssuerString(),
                         status);
 
-        Document assertionDoc = docBuilder.newDocument();
+        Document assertionDoc = DOMUtils.createDocument();
         Element elem = assertion.toDOM(assertionDoc);
 
         Element encryptedAssertionElement =
@@ -416,7 +397,7 @@ public class SAMLEncryptedResponseTest {
         encryptElement(assertionDoc, elem, WSConstants.AES_256, secretKey,
                 WSConstants.KEYTRANSPORT_RSAOAEP, certs[0], false);
 
-        Document doc = docBuilder.newDocument();
+        Document doc = DOMUtils.createDocument();
         Element policyElement = OpenSAMLUtil.toDom(response, doc);
         Element statusElement =
                 (Element)policyElement.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:protocol",
@@ -438,7 +419,7 @@ public class SAMLEncryptedResponseTest {
         assertTrue(found);
     }
 
-    private String encodeResponse(Element response) throws IOException {
+    private static String encodeResponse(Element response) throws IOException {
         String responseMessage = DOM2Writer.nodeToString(response);
 
         byte[] deflatedBytes = CompressionUtils.deflate(responseMessage.getBytes(StandardCharsets.UTF_8));
@@ -446,7 +427,7 @@ public class SAMLEncryptedResponseTest {
         return Base64.getEncoder().encodeToString(deflatedBytes);
     }
 
-    private void encryptElement(
+    private static void encryptElement(
             Document document,
             Element elementToEncrypt,
             String algorithm,
@@ -467,9 +448,6 @@ public class SAMLEncryptedResponseTest {
             org.apache.xml.security.keys.KeyInfo encryptedKeyKeyInfo = encryptedKey.getKeyInfo();
             if (encryptedKeyKeyInfo == null) {
                 encryptedKeyKeyInfo = new org.apache.xml.security.keys.KeyInfo(document);
-                encryptedKeyKeyInfo.getElement().setAttributeNS(
-                        "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
-                );
                 encryptedKey.setKeyInfo(encryptedKeyKeyInfo);
             }
 
@@ -484,9 +462,6 @@ public class SAMLEncryptedResponseTest {
             org.apache.xml.security.keys.KeyInfo builderKeyInfo = builder.getKeyInfo();
             if (builderKeyInfo == null) {
                 builderKeyInfo = new org.apache.xml.security.keys.KeyInfo(document);
-                builderKeyInfo.getElement().setAttributeNS(
-                        "http://www.w3.org/2000/xmlns/", "xmlns:dsig", "http://www.w3.org/2000/09/xmldsig#"
-                );
                 builder.setKeyInfo(builderKeyInfo);
             }