You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2019/11/06 16:41:57 UTC

[ws-wss4j] 02/02: WSS-658 - Enable signature confirmation for signed SAML tokens

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/ws-wss4j.git

commit 04067f19e8d6149f298cce0a97f3ca94391b6e6f
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Wed Nov 6 16:38:59 2019 +0000

    WSS-658 - Enable signature confirmation for signed SAML tokens
---
 .../wss4j/dom/action/SAMLTokenSignedAction.java    |  5 ++
 .../wss4j/dom/action/SAMLTokenUnsignedAction.java  |  5 ++
 .../wss4j/dom/processor/SAMLTokenProcessor.java    |  1 +
 .../dom/handler/SignatureConfirmationTest.java     | 71 ++++++++++++++++++++++
 4 files changed, 82 insertions(+)

diff --git a/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenSignedAction.java b/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenSignedAction.java
index 6dc7366..edf8493 100644
--- a/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenSignedAction.java
+++ b/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenSignedAction.java
@@ -129,7 +129,12 @@ public class SAMLTokenSignedAction implements Action {
                     samlCallback.getIssuerCrypto(),
                     samlCallback.getIssuerKeyName(),
                     samlCallback.getIssuerKeyPassword());
+
             reqData.getSignatureValues().add(wsSign.getSignatureValue());
+            byte[] signatureValue = samlAssertion.getSignatureValue();
+            if (signatureValue != null) {
+                reqData.getSignatureValues().add(signatureValue);
+            }
         } catch (WSSecurityException e) {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, "empty",
                                           new Object[] {"Error when signing the SAML token: "});
diff --git a/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenUnsignedAction.java b/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenUnsignedAction.java
index 6ce7af9..f7cc633 100644
--- a/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenUnsignedAction.java
+++ b/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenUnsignedAction.java
@@ -69,5 +69,10 @@ public class SAMLTokenUnsignedAction implements Action {
 
         // add the SAMLAssertion Token to the SOAP Envelope
         builder.build(samlAssertion);
+
+        byte[] signatureValue = samlAssertion.getSignatureValue();
+        if (signatureValue != null) {
+            reqData.getSignatureValues().add(signatureValue);
+        }
     }
 }
diff --git a/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java b/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
index 44b807f..3bbf47e 100644
--- a/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
+++ b/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/SAMLTokenProcessor.java
@@ -118,6 +118,7 @@ public class SAMLTokenProcessor implements Processor {
         if (samlAssertion.isSigned()) {
             result = new WSSecurityEngineResult(WSConstants.ST_SIGNED, samlAssertion);
             result.put(WSSecurityEngineResult.TAG_DATA_REF_URIS, dataRefs);
+            result.put(WSSecurityEngineResult.TAG_SIGNATURE_VALUE, samlAssertion.getSignatureValue());
         } else {
             result = new WSSecurityEngineResult(WSConstants.ST_UNSIGNED, samlAssertion);
         }
diff --git a/ws-security-dom/src/test/java/org/apache/wss4j/dom/handler/SignatureConfirmationTest.java b/ws-security-dom/src/test/java/org/apache/wss4j/dom/handler/SignatureConfirmationTest.java
index a2f37c4..998b21a 100644
--- a/ws-security-dom/src/test/java/org/apache/wss4j/dom/handler/SignatureConfirmationTest.java
+++ b/ws-security-dom/src/test/java/org/apache/wss4j/dom/handler/SignatureConfirmationTest.java
@@ -30,10 +30,12 @@ import org.apache.wss4j.common.bsp.BSPRule;
 import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.crypto.CryptoFactory;
 import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
 import org.apache.wss4j.common.util.XMLUtils;
 import org.apache.wss4j.dom.WSConstants;
 import org.apache.wss4j.dom.common.CustomHandler;
 import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
+import org.apache.wss4j.dom.common.SAML2CallbackHandler;
 import org.apache.wss4j.dom.common.SOAPUtil;
 import org.apache.wss4j.dom.common.SecurityTestUtil;
 import org.apache.wss4j.dom.engine.WSSecurityEngine;
@@ -372,6 +374,75 @@ public class SignatureConfirmationTest {
         assertFalse(outputString.contains("Value"));
     }
 
+    @SuppressWarnings("unchecked")
+    @Test
+    public void
+    testSAMLSignatureConfirmationProcessing() throws Exception {
+        final RequestData reqData = new RequestData();
+
+        SAML2CallbackHandler samlCallbackHandler = new SAML2CallbackHandler();
+        samlCallbackHandler.setConfirmationMethod(SAML2Constants.CONF_BEARER);
+        samlCallbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
+        samlCallbackHandler.setIssuer("www.example.com");
+        samlCallbackHandler.setSignAssertion(true);
+        samlCallbackHandler.setIssuerCrypto(crypto);
+        samlCallbackHandler.setIssuerName("16c73ab6-b892-458f-abf5-2f875f74882e");
+        samlCallbackHandler.setIssuerPassword("security");
+
+        java.util.Map<String, Object> msgContext = new java.util.TreeMap<>();
+        msgContext.put(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, "true");
+        msgContext.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
+        reqData.setMsgContext(msgContext);
+
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        CustomHandler handler = new CustomHandler();
+        HandlerAction action = new HandlerAction(WSConstants.ST_UNSIGNED);
+        handler.send(
+            doc,
+            reqData,
+            Collections.singletonList(action),
+            true
+        );
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("After Signing....");
+            String outputString =
+                XMLUtils.prettyDocumentToString(doc);
+            LOG.debug(outputString);
+        }
+
+        //
+        // Verify the inbound request, and create a response with a Signature Confirmation
+        //
+        WSHandlerResult results = verify(doc);
+        doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        msgContext = (java.util.Map<String, Object>)reqData.getMsgContext();
+        List<WSHandlerResult> receivedResults = new ArrayList<>();
+        receivedResults.add(results);
+        msgContext.put(WSHandlerConstants.RECV_RESULTS, receivedResults);
+        handler.send(
+            doc,
+            reqData,
+            Collections.singletonList(new HandlerAction(WSConstants.NO_SECURITY)),
+            false
+        );
+        String outputString =
+            XMLUtils.prettyDocumentToString(doc);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Signature Confirmation response....");
+            LOG.debug(outputString);
+        }
+
+        //
+        // Verify the SignatureConfirmation response
+        //
+        results = verify(doc);
+        WSSecurityEngineResult scResult =
+            results.getActionResults().get(WSConstants.SC).get(0);
+        assertNotNull(scResult);
+        assertNotNull(scResult.get(WSSecurityEngineResult.TAG_SIGNATURE_CONFIRMATION));
+        handler.signatureConfirmation(reqData, results);
+    }
+
     /**
      * Verifies the soap envelope
      * <p/>