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 2014/09/10 18:19:57 UTC

svn commit: r1624053 - in /webservices/wss4j/branches/1_6_x-fixes/src: main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java

Author: coheigea
Date: Wed Sep 10 16:19:56 2014
New Revision: 1624053

URL: http://svn.apache.org/r1624053
Log:
Record SAML Token signed results so that it can be used in SignedElements evaluation.


Conflicts:
	src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
	src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java

Modified:
    webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
    webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java

Modified: webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java?rev=1624053&r1=1624052&r2=1624053&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/main/java/org/apache/ws/security/processor/SAMLTokenProcessor.java Wed Sep 10 16:19:56 2014
@@ -21,6 +21,7 @@ package org.apache.ws.security.processor
 
 import org.apache.ws.security.SAMLTokenPrincipal;
 import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSDataRef;
 import org.apache.ws.security.WSDocInfo;
 import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.WSSecurityException;
@@ -33,16 +34,18 @@ import org.apache.ws.security.saml.ext.A
 import org.apache.ws.security.util.DOM2Writer;
 import org.apache.ws.security.validate.Credential;
 import org.apache.ws.security.validate.Validator;
-
 import org.opensaml.xml.signature.KeyInfo;
 import org.opensaml.xml.signature.Signature;
 import org.w3c.dom.Element;
 
 import java.security.NoSuchProviderException;
 import java.security.PublicKey;
+import java.util.ArrayList;
 import java.util.List;
 
 import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.Transform;
 import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.XMLSignatureFactory;
 import javax.xml.crypto.dsig.XMLValidateContext;
@@ -75,15 +78,22 @@ public class SAMLTokenProcessor implemen
         
         Validator validator = 
             data.getValidator(new QName(elem.getNamespaceURI(), elem.getLocalName()));
-        Credential credential = handleSAMLToken(elem, data, validator, wsDocInfo);
-        AssertionWrapper assertion = credential.getAssertion();
+        
+        AssertionWrapper samlAssertion = new AssertionWrapper(elem);
+        XMLSignature xmlSignature = 
+            verifySignatureKeysAndAlgorithms(samlAssertion, data, wsDocInfo);
+        List<WSDataRef> dataRefs = createDataRefs(elem, samlAssertion, xmlSignature);
+        
+        Credential credential = 
+            handleSAMLToken(samlAssertion, data, validator, wsDocInfo);
+        samlAssertion = credential.getAssertion();
         if (log.isDebugEnabled()) {
-            log.debug("SAML Assertion issuer " + assertion.getIssuerString());
+            log.debug("SAML Assertion issuer " + samlAssertion.getIssuerString());
             log.debug(DOM2Writer.nodeToString(elem));
         }
         
         // See if the token has been previously processed
-        String id = assertion.getId();
+        String id = samlAssertion.getId();
         Element foundElement = wsDocInfo.getTokenElement(id);
         if (elem.equals(foundElement)) {
             WSSecurityEngineResult result = wsDocInfo.getResult(id);
@@ -96,10 +106,11 @@ public class SAMLTokenProcessor implemen
 
         wsDocInfo.addTokenElement(elem);
         WSSecurityEngineResult result = null;
-        if (assertion.isSigned()) {
-            result = new WSSecurityEngineResult(WSConstants.ST_SIGNED, assertion);
+        if (samlAssertion.isSigned()) {
+            result = new WSSecurityEngineResult(WSConstants.ST_SIGNED, samlAssertion);
+            result.put(WSSecurityEngineResult.TAG_DATA_REF_URIS, dataRefs);
         } else {
-            result = new WSSecurityEngineResult(WSConstants.ST_UNSIGNED, assertion);
+            result = new WSSecurityEngineResult(WSConstants.ST_UNSIGNED, samlAssertion);
         }
         
         if (!"".equals(id)) {
@@ -122,7 +133,7 @@ public class SAMLTokenProcessor implemen
             } else if (credential.getPrincipal() != null) {
                 result.put(WSSecurityEngineResult.TAG_PRINCIPAL, credential.getPrincipal());
             } else {
-                result.put(WSSecurityEngineResult.TAG_PRINCIPAL, new SAMLTokenPrincipal(assertion));
+                result.put(WSSecurityEngineResult.TAG_PRINCIPAL, new SAMLTokenPrincipal(samlAssertion));
             }
             result.put(WSSecurityEngineResult.TAG_SUBJECT, credential.getSubject());
         }
@@ -131,17 +142,30 @@ public class SAMLTokenProcessor implemen
     }
 
     public Credential handleSAMLToken(
-        Element token, 
+        AssertionWrapper samlAssertion, 
         RequestData data,
         Validator validator,
         WSDocInfo docInfo
     ) throws WSSecurityException {
-        AssertionWrapper assertion = new AssertionWrapper(token);
-        if (assertion.isSigned()) {
-            // Check for compliance against the defined AlgorithmSuite
-            AlgorithmSuite algorithmSuite = data.getSamlAlgorithmSuite();
+        // Parse the subject if it exists
+        samlAssertion.parseHOKSubject(data, docInfo);
             
-            Signature sig = assertion.getSignature();
+        // Now delegate the rest of the verification to the Validator
+        Credential credential = new Credential();
+        credential.setAssertion(samlAssertion);
+        if (validator != null) {
+            return validator.validate(credential, data);
+        }
+        return credential;
+    }
+    
+    private XMLSignature verifySignatureKeysAndAlgorithms(
+        AssertionWrapper samlAssertion,
+        RequestData data,
+        WSDocInfo wsDocInfo
+    ) throws WSSecurityException {
+        if (samlAssertion.isSigned()) {
+            Signature sig = samlAssertion.getSignature();
             KeyInfo keyInfo = sig.getKeyInfo();
             if (keyInfo == null) {
                 throw new WSSecurityException(
@@ -151,57 +175,92 @@ public class SAMLTokenProcessor implemen
             }
             SAMLKeyInfo samlKeyInfo = 
                 SAMLUtil.getCredentialFromKeyInfo(
-                    keyInfo.getDOM(), data, docInfo, data.getWssConfig().isWsiBSPCompliant()
+                    keyInfo.getDOM(), data, wsDocInfo, data.getWssConfig().isWsiBSPCompliant()
+                );
+            
+            PublicKey key = null;
+            if (samlKeyInfo.getCerts() != null && samlKeyInfo.getCerts()[0] != null) {
+                key = samlKeyInfo.getCerts()[0].getPublicKey();
+            } else if (samlKeyInfo.getPublicKey() != null) {
+                key = samlKeyInfo.getPublicKey();
+            } else {
+                throw new WSSecurityException(
+                    WSSecurityException.FAILURE, "invalidSAMLsecurity",
+                    new Object[]{"cannot get certificate or key"}
+                );
+            }
+            
+            // Not checking signature here, just marshalling into an XMLSignature
+            // structure for testing the transform/digest algorithms etc.
+            XMLValidateContext context = new DOMValidateContext(key, sig.getDOM());
+            context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
+            context.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
+
+            XMLSignature xmlSignature;
+            try {
+                xmlSignature = signatureFactory.unmarshalXMLSignature(context);
+            } catch (MarshalException ex) {
+                throw new WSSecurityException(
+                    WSSecurityException.FAILED_CHECK, "invalidSAMLsecurity", 
+                    new Object[]{"cannot get certificate or key"}, ex
                 );
+            }
             
+            // Check for compliance against the defined AlgorithmSuite
+            AlgorithmSuite algorithmSuite = data.getSamlAlgorithmSuite();
             if (algorithmSuite != null) {
                 AlgorithmSuiteValidator algorithmSuiteValidator = new
                     AlgorithmSuiteValidator(algorithmSuite);
 
-                PublicKey key = null;
-                if (samlKeyInfo.getCerts() != null && samlKeyInfo.getCerts()[0] != null) {
-                    key = samlKeyInfo.getCerts()[0].getPublicKey();
-                } else if (samlKeyInfo.getPublicKey() != null) {
-                    key = samlKeyInfo.getPublicKey();
-                } else {
-                    throw new WSSecurityException(
-                        WSSecurityException.FAILURE, "invalidSAMLsecurity",
-                        new Object[]{"cannot get certificate or key"}
-                    );
-                }
-            
-                // Not checking signature here, just marshalling into an XMLSignature
-                // structure for testing the transform/digest algorithms etc.
-                XMLValidateContext context = new DOMValidateContext(key, sig.getDOM());
-                context.setProperty("org.apache.jcp.xml.dsig.secureValidation", Boolean.TRUE);
-                context.setProperty("org.jcp.xml.dsig.secureValidation", Boolean.TRUE);
-
-                XMLSignature xmlSignature;
-                try {
-                    xmlSignature = signatureFactory.unmarshalXMLSignature(context);
-                } catch (MarshalException ex) {
-                    throw new WSSecurityException(
-                        WSSecurityException.FAILED_CHECK, "invalidSAMLsecurity", 
-                        new Object[]{"cannot get certificate or key"}, ex
-                    );
-                }
-
                 algorithmSuiteValidator.checkSignatureAlgorithms(xmlSignature);
                 algorithmSuiteValidator.checkAsymmetricKeyLength(key);
             }
 
-            assertion.verifySignature(samlKeyInfo);
-        }
-        // Parse the HOK subject if it exists
-        assertion.parseHOKSubject(data, docInfo);
+            samlAssertion.verifySignature(samlKeyInfo);
             
-        // Now delegate the rest of the verification to the Validator
-        Credential credential = new Credential();
-        credential.setAssertion(assertion);
-        if (validator != null) {
-            return validator.validate(credential, data);
+            return xmlSignature;
         }
-        return credential;
+        
+        return null;
     }
 
+    private List<WSDataRef> createDataRefs(
+        Element token, AssertionWrapper samlAssertion, XMLSignature xmlSignature
+    ) {
+        if (xmlSignature == null) {
+            return null;
+        }
+        
+        List<WSDataRef> protectedRefs = new ArrayList<WSDataRef>();
+        String signatureMethod = 
+            xmlSignature.getSignedInfo().getSignatureMethod().getAlgorithm();
+        
+        for (Object refObject : xmlSignature.getSignedInfo().getReferences()) {
+            Reference reference = (Reference)refObject;
+            
+            if ("".equals(reference.getURI()) 
+                || reference.getURI().equals(samlAssertion.getId())
+                || reference.getURI().equals("#" + samlAssertion.getId())) {
+                WSDataRef ref = new WSDataRef();
+                ref.setWsuId(reference.getURI());
+                ref.setProtectedElement(token);
+                ref.setAlgorithm(signatureMethod);
+                ref.setDigestAlgorithm(reference.getDigestMethod().getAlgorithm());
+    
+                // Set the Transform algorithms as well
+                @SuppressWarnings("unchecked")
+                List<Transform> transforms = (List<Transform>)reference.getTransforms();
+                List<String> transformAlgorithms = new ArrayList<String>(transforms.size());
+                for (Transform transform : transforms) {
+                    transformAlgorithms.add(transform.getAlgorithm());
+                }
+                ref.setTransformAlgorithms(transformAlgorithms);
+    
+                ref.setXpath(ReferenceListProcessor.getXPath(token));
+                protectedRefs.add(ref);
+            }
+        }
+        
+        return protectedRefs;
+    }
 }

Modified: webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java?rev=1624053&r1=1624052&r2=1624053&view=diff
==============================================================================
--- webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java (original)
+++ webservices/wss4j/branches/1_6_x-fixes/src/test/java/org/apache/ws/security/saml/SignedSamlTokenHOKTest.java Wed Sep 10 16:19:56 2014
@@ -130,16 +130,24 @@ public class SignedSamlTokenHOKTest exte
         assertTrue(receivedAssertion.isSigned());
         assertTrue(receivedAssertion.getSignatureValue() != null);
         
+        // Test we have a WSDataRef for the signed SAML token as well
+        List<WSDataRef> refs =
+            (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+        assertTrue(refs.size() == 1);
+        
+        WSDataRef wsDataRef = refs.get(0);
+        String xpath = wsDataRef.getXpath();
+        assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/saml1:Assertion", xpath);
+        
         // Test we processed a signature (SOAP body)
         actionResult = WSSecurityUtil.fetchActionResult(results, WSConstants.SIGN);
         assertTrue(actionResult != null);
         assertFalse(actionResult.isEmpty());
-        final List<WSDataRef> refs =
-            (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
+        refs = (List<WSDataRef>) actionResult.get(WSSecurityEngineResult.TAG_DATA_REF_URIS);
         assertTrue(refs.size() == 1);
         
-        WSDataRef wsDataRef = (WSDataRef)refs.get(0);
-        String xpath = wsDataRef.getXpath();
+        wsDataRef = refs.get(0);
+        xpath = wsDataRef.getXpath();
         assertEquals("/SOAP-ENV:Envelope/SOAP-ENV:Body", xpath);
     }