You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2020/06/15 15:35:50 UTC

[cxf-fediz] branch master updated: FEDIZ-247 - Adding an @Ignore'd unit test

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 811ed1f  FEDIZ-247 - Adding an @Ignore'd unit test
811ed1f is described below

commit 811ed1ffcae3dc3cdc4d9f7b41a5d80fc74c21ab
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Mon Jun 15 16:35:24 2020 +0100

    FEDIZ-247 - Adding an @Ignore'd unit test
---
 .../cxf/fediz/core/samlsso/SAMLResponseTest.java   | 185 ++++++++++++++++++++-
 .../src/test/resources/fediz_test_config_saml.xml  |  32 ++++
 2 files changed, 213 insertions(+), 4 deletions(-)

diff --git a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java
index f612e6f..3e83eb8 100644
--- a/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java
+++ b/plugins/core/src/test/java/org/apache/cxf/fediz/core/samlsso/SAMLResponseTest.java
@@ -26,6 +26,7 @@ import java.net.URI;
 import java.net.URL;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
+import java.security.Key;
 import java.security.PrivateKey;
 import java.security.cert.X509Certificate;
 import java.util.Base64;
@@ -33,6 +34,8 @@ import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
 
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.servlet.http.HttpServletRequest;
@@ -78,6 +81,10 @@ import org.apache.wss4j.common.saml.bean.SubjectConfirmationDataBean;
 import org.apache.wss4j.common.saml.builder.SAML2Constants;
 import org.apache.wss4j.common.util.DOM2Writer;
 import org.apache.wss4j.dom.WSConstants;
+import org.apache.xml.security.encryption.EncryptedData;
+import org.apache.xml.security.encryption.EncryptedKey;
+import org.apache.xml.security.encryption.XMLCipher;
+import org.apache.xml.security.keys.content.X509Data;
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 import org.opensaml.saml.common.SAMLObjectContentReference;
@@ -96,6 +103,8 @@ import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 /**
@@ -1225,7 +1234,7 @@ public class SAMLResponseTest {
 
         NodeList assertionNodes =
             policyElement.getElementsByTagNameNS(WSConstants.SAML2_NS, "Assertion");
-        Assert.assertTrue(assertionNodes != null && assertionNodes.getLength() == 1);
+        assertTrue(assertionNodes != null && assertionNodes.getLength() == 1);
 
         Element assertionElement = (Element)assertionNodes.item(0);
 
@@ -1547,6 +1556,58 @@ public class SAMLResponseTest {
         }
     }
 
+    @org.junit.Test
+    @org.junit.Ignore // TODO https://issues.apache.org/jira/browse/FEDIZ-247
+    public void validateEncryptedSAMLResponse() throws Exception {
+        // Mock up a Request
+        //FedizContext config = getFederationConfigurator().getFedizContext("ROOT");
+        FedizContext config =
+                getFederationConfigurator().getFedizContext("ROOT_DECRYPTION");
+
+        String requestId = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+
+        String relayState = URLEncoder.encode(UUID.randomUUID().toString(), "UTF-8");
+        RequestState requestState = new RequestState(TEST_REQUEST_URL,
+                TEST_IDP_ISSUER,
+                requestId,
+                TEST_REQUEST_URL,
+                (String)config.getProtocol().getIssuer(),
+                null,
+                relayState,
+                System.currentTimeMillis());
+
+        // Create SAML Response
+        SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
+        callbackHandler.setAlsoAddAuthnStatement(true);
+        callbackHandler.setStatement(SAML2CallbackHandler.Statement.ATTR);
+        callbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+        callbackHandler.setIssuer(TEST_IDP_ISSUER);
+        callbackHandler.setSubjectName(TEST_USER);
+        String responseStr = createSamlResponseStr(callbackHandler, requestId, true);
+
+        HttpServletRequest req = EasyMock.createMock(HttpServletRequest.class);
+        EasyMock.expect(req.getRequestURL()).andReturn(new StringBuffer(TEST_REQUEST_URL));
+        EasyMock.expect(req.getRemoteAddr()).andReturn(TEST_CLIENT_ADDRESS);
+        EasyMock.replay(req);
+
+        FedizRequest wfReq = new FedizRequest();
+        wfReq.setResponseToken(responseStr);
+        wfReq.setState(relayState);
+        wfReq.setRequest(req);
+        wfReq.setRequestState(requestState);
+
+        FedizProcessor wfProc = new SAMLProcessorImpl();
+        FedizResponse wfRes = wfProc.processRequest(wfReq, config);
+
+        Assert.assertEquals("Principal name wrong", TEST_USER,
+                wfRes.getUsername());
+        Assert.assertEquals("Issuer wrong", TEST_IDP_ISSUER, wfRes.getIssuer());
+        Assert.assertEquals("Two roles must be found", 2, wfRes.getRoles()
+                .size());
+        Assert.assertEquals("Audience wrong", TEST_REQUEST_URL, wfRes.getAudience());
+        assertClaims(wfRes.getClaims(), ClaimTypes.COUNTRY);
+    }
+
     private String createSamlResponseStr(String requestId) throws Exception {
         // Create SAML Assertion
         SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
@@ -1561,6 +1622,12 @@ public class SAMLResponseTest {
 
     private String createSamlResponseStr(AbstractSAMLCallbackHandler saml2CallbackHandler,
                                          String requestId) throws Exception {
+        return createSamlResponseStr(saml2CallbackHandler, requestId, false);
+    }
+
+    private String createSamlResponseStr(AbstractSAMLCallbackHandler saml2CallbackHandler,
+                                         String requestId,
+                                         boolean encryptAssertion) throws Exception {
         ConditionsBean cp = new ConditionsBean();
         AudienceRestrictionBean audienceRestriction = new AudienceRestrictionBean();
         audienceRestriction.getAudienceURIs().add(TEST_REQUEST_URL);
@@ -1578,6 +1645,11 @@ public class SAMLResponseTest {
         SAMLCallback samlCallback = new SAMLCallback();
         SAMLUtil.doSAMLCallback(saml2CallbackHandler, samlCallback);
         SamlAssertionWrapper assertion = new SamlAssertionWrapper(samlCallback);
+
+        if (encryptAssertion) {
+            Element response = createEncryptedSamlResponse(assertion, "mystskey", true, requestId);
+            return encodeResponse(response);
+        }
         Element response = createSamlResponse(assertion, "mystskey", true, requestId);
         return encodeResponse(response);
     }
@@ -1596,7 +1668,6 @@ public class SAMLResponseTest {
         }
 
         DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
-        Document doc = docBuilder.newDocument();
 
         Status status =
             SAML2PResponseComponentBuilder.createStatus(
@@ -1606,15 +1677,71 @@ public class SAMLResponseTest {
             SAML2PResponseComponentBuilder.createSAMLResponse(requestID,
                                                               assertion.getIssuerString(),
                                                               status);
-
         response.getAssertions().add(assertion.getSaml2());
 
+        Document doc = docBuilder.newDocument();
         Element policyElement = OpenSAMLUtil.toDom(response, doc);
         doc.appendChild(policyElement);
 
         return policyElement;
     }
 
+    private Element createEncryptedSamlResponse(SamlAssertionWrapper assertion, String alias,
+                                       boolean sign, String requestID)
+            throws IOException, UnsupportedCallbackException, WSSecurityException, Exception {
+        WSPasswordCallback[] cb = {new WSPasswordCallback(alias, WSPasswordCallback.SIGNATURE)};
+        cbPasswordHandler.handle(cb);
+        String password = cb[0].getPassword();
+
+        if (sign) {
+            assertion.signAssertion(alias, password, crypto, false);
+        }
+
+        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+
+        Status status =
+                SAML2PResponseComponentBuilder.createStatus(
+                        "urn:oasis:names:tc:SAML:2.0:status:Success", null
+                );
+        Response response =
+                SAML2PResponseComponentBuilder.createSAMLResponse(requestID,
+                        assertion.getIssuerString(),
+                        status);
+
+        Document assertionDoc = docBuilder.newDocument();
+        Element elem = assertion.toDOM(assertionDoc);
+
+        Element encryptedAssertionElement =
+                assertionDoc.createElementNS(WSConstants.SAML2_NS, WSConstants.ENCRYPED_ASSERTION_LN);
+        encryptedAssertionElement.setAttributeNS(
+                WSConstants.XMLNS_NS, "xmlns", WSConstants.SAML2_NS
+        );
+        encryptedAssertionElement.appendChild(elem);
+        assertionDoc.appendChild(encryptedAssertionElement);
+
+        // Encrypt the Assertion
+        KeyGenerator keygen = KeyGenerator.getInstance("AES");
+        keygen.init(256);
+        SecretKey secretKey = keygen.generateKey();
+        CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+        cryptoType.setAlias("mystskey");
+        X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
+        assertTrue(certs != null && certs.length > 0 && certs[0] != null);
+
+        encryptElement(assertionDoc, elem, WSConstants.AES_256, secretKey,
+                WSConstants.KEYTRANSPORT_RSAOAEP, certs[0], false);
+
+        Document doc = docBuilder.newDocument();
+        Element policyElement = OpenSAMLUtil.toDom(response, doc);
+        Element statusElement =
+                (Element)policyElement.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:protocol",
+                        "Status").item(0);
+        assertNotNull(statusElement);
+        policyElement.appendChild(doc.importNode(encryptedAssertionElement, true));
+
+        return policyElement;
+    }
+
     private Element createLogoutResponse(String statusValue, String destination,
                                          boolean sign, String requestID) throws Exception {
         DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
@@ -1704,7 +1831,7 @@ public class SAMLResponseTest {
                 break;
             }
         }
-        Assert.assertTrue(found);
+        assertTrue(found);
     }
 
     private String encodeResponse(Element response) throws IOException {
@@ -1715,5 +1842,55 @@ public class SAMLResponseTest {
         return Base64.getEncoder().encodeToString(deflatedBytes);
     }
 
+    private void encryptElement(
+            Document document,
+            Element elementToEncrypt,
+            String algorithm,
+            Key encryptingKey,
+            String keyTransportAlgorithm,
+            X509Certificate wrappingCert,
+            boolean content
+    ) throws Exception {
+        XMLCipher cipher = XMLCipher.getInstance(algorithm);
+        cipher.init(XMLCipher.ENCRYPT_MODE, encryptingKey);
+
+        if (wrappingCert != null) {
+            XMLCipher newCipher = XMLCipher.getInstance(keyTransportAlgorithm);
+            newCipher.init(XMLCipher.WRAP_MODE, wrappingCert.getPublicKey());
+
+            EncryptedKey encryptedKey = newCipher.encryptKey(document, encryptingKey);
+            // Create a KeyInfo for the EncryptedKey
+            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);
+            }
+
+            X509Data x509Data = new X509Data(document);
+            // x509Data.addCertificate(wrappingCert);
+            x509Data.addIssuerSerial(wrappingCert.getIssuerX500Principal().getName(),
+                    wrappingCert.getSerialNumber());
+            encryptedKeyKeyInfo.add(x509Data);
+
+            // Create a KeyInfo for the EncryptedData
+            EncryptedData builder = cipher.getEncryptedData();
+            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);
+            }
+
+            builderKeyInfo.add(encryptedKey);
+        }
+
+        cipher.doFinal(document, elementToEncrypt, content);
+    }
+
 
 }
diff --git a/plugins/core/src/test/resources/fediz_test_config_saml.xml b/plugins/core/src/test/resources/fediz_test_config_saml.xml
index 9147445..ff84520 100644
--- a/plugins/core/src/test/resources/fediz_test_config_saml.xml
+++ b/plugins/core/src/test/resources/fediz_test_config_saml.xml
@@ -332,4 +332,36 @@
 		<logoutURL>secure/logout</logoutURL>
         <logoutRedirectTo>/redir.html</logoutRedirectTo>
 	</contextConfig>
+
+	<contextConfig name="ROOT_DECRYPTION">
+		<audienceUris>
+			<audienceItem>http://host_one:port/url</audienceItem>
+		</audienceUris>
+		<certificateStores>
+			<trustManager>
+				<keyStore file="ststrust.jks" password="storepass"
+						  type="JKS" />
+			</trustManager>
+		</certificateStores>
+		<trustedIssuers>
+			<issuer certificateValidation="PeerTrust" />
+		</trustedIssuers>
+		<tokenDecryptionKey keyPassword="stskpass" keyAlias="mystskey">
+			<keyStore file="stsstore.jks" password="stsspass" type="JKS" />
+		</tokenDecryptionKey>
+
+		<maximumClockSkew>1000</maximumClockSkew>
+		<protocol xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+				  xsi:type="samlProtocolType" version="1.2">
+			<issuer>http://url_to_the_issuer</issuer>
+			<roleDelimiter>;</roleDelimiter>
+			<roleURI>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role</roleURI>
+			<claimTypesRequested>
+				<claimType type="a particular claim type" optional="true" />
+			</claimTypesRequested>
+		</protocol>
+
+		<logoutURL>secure/logout</logoutURL>
+		<logoutRedirectTo>/redir.html</logoutRedirectTo>
+	</contextConfig>
 </FedizConfig>