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/02/12 12:41:01 UTC

svn commit: r1567601 - in /webservices/wss4j/trunk: ws-security-dom/src/main/java/org/apache/wss4j/dom/action/ ws-security-dom/src/main/java/org/apache/wss4j/dom/message/ ws-security-dom/src/test/java/org/apache/wss4j/dom/common/ ws-security-dom/src/te...

Author: coheigea
Date: Wed Feb 12 11:41:00 2014
New Revision: 1567601

URL: http://svn.apache.org/r1567601
Log:
Added the ability to sign a SAML Assertion directly

Added:
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlTokenActionTest.java
Modified:
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenSignedAction.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenUnsignedAction.java
    webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecBase.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/AbstractSAMLCallbackHandler.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/SAML1CallbackHandler.java
    webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/SAML2CallbackHandler.java
    webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/resourceResolvers/ResolverSameDocument.java

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenSignedAction.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenSignedAction.java?rev=1567601&r1=1567600&r2=1567601&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenSignedAction.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenSignedAction.java Wed Feb 12 11:41:00 2014
@@ -76,11 +76,6 @@ public class SAMLTokenSignedAction imple
         
         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
         if (samlCallback.isSignAssertion()) {
-            Crypto signingCrypto = samlCallback.getIssuerCrypto();
-            if (signingCrypto == null) {
-                signingCrypto = handler.loadSignatureCrypto(reqData);
-            }
-            
             samlAssertion.signAssertion(
                 samlCallback.getIssuerKeyName(),
                 samlCallback.getIssuerKeyPassword(), 

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenUnsignedAction.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenUnsignedAction.java?rev=1567601&r1=1567600&r2=1567601&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenUnsignedAction.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/SAMLTokenUnsignedAction.java Wed Feb 12 11:41:00 2014
@@ -22,7 +22,6 @@ package org.apache.wss4j.dom.action;
 import javax.security.auth.callback.CallbackHandler;
 
 import org.apache.wss4j.common.SecurityActionToken;
-import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
 import org.apache.wss4j.common.saml.SAMLCallback;
@@ -57,11 +56,6 @@ public class SAMLTokenUnsignedAction imp
 
         SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
         if (samlCallback.isSignAssertion()) {
-            Crypto signingCrypto = samlCallback.getIssuerCrypto();
-            if (signingCrypto == null) {
-                signingCrypto = handler.loadSignatureCrypto(reqData);
-            }
-            
             samlAssertion.signAssertion(
                 samlCallback.getIssuerKeyName(),
                 samlCallback.getIssuerKeyPassword(), 

Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecBase.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecBase.java?rev=1567601&r1=1567600&r2=1567601&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecBase.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecBase.java Wed Feb 12 11:41:00 2014
@@ -152,16 +152,23 @@ public class WSSecBase {
         String newAttrNs = WSConstants.WSU_NS;
         String newAttrPrefix = WSConstants.WSU_PREFIX;
 
-        if ((id == null || id.length() == 0)
-            && WSConstants.ENC_NS.equals(bodyElement.getNamespaceURI())
-            && (WSConstants.ENC_DATA_LN.equals(bodyElement.getLocalName())
-                || WSConstants.ENC_KEY_LN.equals(bodyElement.getLocalName()))
-        ) {
-            // If it is an XML-Enc derived element, it may already have an ID,
-            // plus it is not schema valid to add an additional ID.
-            id = bodyElement.getAttributeNS(null, "Id");
-            newAttrPrefix = WSConstants.ENC_PREFIX;
-            newAttrNs = WSConstants.ENC_NS;
+        if (id == null || id.length() == 0) {
+            if (WSConstants.ENC_NS.equals(bodyElement.getNamespaceURI())
+                && (WSConstants.ENC_DATA_LN.equals(bodyElement.getLocalName())
+                    || WSConstants.ENC_KEY_LN.equals(bodyElement.getLocalName()))
+                ) {
+                // If it is an XML-Enc derived element, it may already have an ID,
+                // plus it is not schema valid to add an additional ID.
+                id = bodyElement.getAttributeNS(null, "Id");
+                newAttrPrefix = WSConstants.ENC_PREFIX;
+                newAttrNs = WSConstants.ENC_NS;
+            } else if (WSConstants.SAML_NS.equals(bodyElement.getNamespaceURI())
+                && "Assertion".equals(bodyElement.getLocalName())) {
+                id = bodyElement.getAttributeNS(null, "AssertionID");
+            } else if (WSConstants.SAML2_NS.equals(bodyElement.getNamespaceURI())
+                && "Assertion".equals(bodyElement.getLocalName())) {
+                id = bodyElement.getAttributeNS(null, "ID");
+            }
         }
         
         if (id == null || id.length() == 0) {

Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/AbstractSAMLCallbackHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/AbstractSAMLCallbackHandler.java?rev=1567601&r1=1567600&r2=1567601&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/AbstractSAMLCallbackHandler.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/AbstractSAMLCallbackHandler.java Wed Feb 12 11:41:00 2014
@@ -20,6 +20,7 @@
 package org.apache.wss4j.dom.common;
 
 import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.common.crypto.Crypto;
 import org.apache.wss4j.common.saml.SAMLCallback;
 import org.apache.wss4j.common.saml.bean.ActionBean;
 import org.apache.wss4j.common.saml.bean.AttributeBean;
@@ -72,6 +73,9 @@ public abstract class AbstractSAMLCallba
     protected List<Object> customAttributeValues = null;
     protected ConditionsBean conditions = null;
     protected SubjectConfirmationDataBean subjectConfirmationData = null;
+    private Crypto issuerCrypto;
+    private String issuerName;
+    private String issuerPassword;
     
     public void setSubjectConfirmationData(SubjectConfirmationDataBean subjectConfirmationData) {
         this.subjectConfirmationData = subjectConfirmationData;
@@ -213,4 +217,28 @@ public abstract class AbstractSAMLCallba
         }
         return keyInfo;
     }
+
+    public Crypto getIssuerCrypto() {
+        return issuerCrypto;
+    }
+
+    public void setIssuerCrypto(Crypto issuerCrypto) {
+        this.issuerCrypto = issuerCrypto;
+    }
+
+    public String getIssuerName() {
+        return issuerName;
+    }
+
+    public void setIssuerName(String issuerName) {
+        this.issuerName = issuerName;
+    }
+
+    public String getIssuerPassword() {
+        return issuerPassword;
+    }
+
+    public void setIssuerPassword(String issuerPassword) {
+        this.issuerPassword = issuerPassword;
+    }
 }

Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/SAML1CallbackHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/SAML1CallbackHandler.java?rev=1567601&r1=1567600&r2=1567601&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/SAML1CallbackHandler.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/SAML1CallbackHandler.java Wed Feb 12 11:41:00 2014
@@ -63,6 +63,9 @@ public class SAML1CallbackHandler extend
                 if (conditions != null) {
                     callback.setConditions(conditions);
                 }
+                callback.setIssuerCrypto(getIssuerCrypto());
+                callback.setIssuerKeyName(getIssuerName());
+                callback.setIssuerKeyPassword(getIssuerPassword());
                 
                 SubjectBean subjectBean = 
                     new SubjectBean(

Modified: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/SAML2CallbackHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/SAML2CallbackHandler.java?rev=1567601&r1=1567600&r2=1567601&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/SAML2CallbackHandler.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/common/SAML2CallbackHandler.java Wed Feb 12 11:41:00 2014
@@ -61,6 +61,9 @@ public class SAML2CallbackHandler extend
                 if (conditions != null) {
                     callback.setConditions(conditions);
                 }
+                callback.setIssuerCrypto(getIssuerCrypto());
+                callback.setIssuerKeyName(getIssuerName());
+                callback.setIssuerKeyPassword(getIssuerPassword());
                 
                 SubjectBean subjectBean = 
                     new SubjectBean(

Added: webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlTokenActionTest.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlTokenActionTest.java?rev=1567601&view=auto
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlTokenActionTest.java (added)
+++ webservices/wss4j/trunk/ws-security-dom/src/test/java/org/apache/wss4j/dom/saml/SamlTokenActionTest.java Wed Feb 12 11:41:00 2014
@@ -0,0 +1,193 @@
+/**
+ * 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.wss4j.dom.saml;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.security.auth.callback.CallbackHandler;
+
+import org.w3c.dom.Document;
+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.util.XMLUtils;
+import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.dom.WSSConfig;
+import org.apache.wss4j.dom.WSSecurityEngine;
+import org.apache.wss4j.dom.WSSecurityEngineResult;
+import org.apache.wss4j.dom.common.CustomHandler;
+import org.apache.wss4j.dom.common.CustomSamlAssertionValidator;
+import org.apache.wss4j.dom.common.KeystoreCallbackHandler;
+import org.apache.wss4j.dom.common.SAML1CallbackHandler;
+import org.apache.wss4j.dom.common.SOAPUtil;
+import org.apache.wss4j.dom.common.SecurityTestUtil;
+import org.apache.wss4j.dom.handler.HandlerAction;
+import org.apache.wss4j.dom.handler.RequestData;
+import org.apache.wss4j.dom.handler.WSHandlerConstants;
+
+/**
+ * Test-case for sending SAML Assertions using the "action" approach.
+ */
+public class SamlTokenActionTest extends org.junit.Assert {
+    private static final org.slf4j.Logger LOG = 
+        org.slf4j.LoggerFactory.getLogger(SamlTokenActionTest.class);
+    private WSSecurityEngine secEngine = new WSSecurityEngine();
+    private Crypto crypto = null;
+    
+    @org.junit.AfterClass
+    public static void cleanup() throws Exception {
+        SecurityTestUtil.cleanup();
+    }
+
+    public SamlTokenActionTest() throws WSSecurityException {
+        WSSConfig config = WSSConfig.getNewInstance();
+        crypto = CryptoFactory.getInstance("wss40.properties");
+        config.setValidator(WSSecurityEngine.SAML_TOKEN, new CustomSamlAssertionValidator());
+        config.setValidator(WSSecurityEngine.SAML2_TOKEN, new CustomSamlAssertionValidator());
+        config.setValidateSamlSubjectConfirmation(false);
+        secEngine.setWssConfig(config);
+    }
+    
+    @org.junit.Test
+    public void testAssertionAction() throws Exception {
+        final WSSConfig cfg = WSSConfig.getNewInstance();
+        final RequestData reqData = new RequestData();
+        reqData.setWssConfig(cfg);
+        reqData.setUsername("wss40");
+        
+        CallbackHandler callbackHandler = new KeystoreCallbackHandler();
+        
+        SAML1CallbackHandler samlCallbackHandler = new SAML1CallbackHandler();
+        samlCallbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+        samlCallbackHandler.setIssuer("www.example.com");
+        
+        java.util.Map<String, Object> config = new java.util.TreeMap<String, Object>();
+        config.put(WSHandlerConstants.SIG_PROP_FILE, "wss40.properties");
+        config.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
+        config.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
+        reqData.setMsgContext(config);
+        
+        final 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()) {
+            String outputString = XMLUtils.PrettyDocumentToString(doc);
+            LOG.debug(outputString);
+        }
+        
+        verify(doc, callbackHandler);
+    }
+    
+    @org.junit.Test
+    public void testSignedAssertionAction() throws Exception {
+        final WSSConfig cfg = WSSConfig.getNewInstance();
+        final RequestData reqData = new RequestData();
+        reqData.setWssConfig(cfg);
+        
+        CallbackHandler callbackHandler = new KeystoreCallbackHandler();
+        
+        SAML1CallbackHandler samlCallbackHandler = new SAML1CallbackHandler();
+        samlCallbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+        samlCallbackHandler.setIssuer("www.example.com");
+        samlCallbackHandler.setIssuerCrypto(crypto);
+        samlCallbackHandler.setIssuerName("wss40");
+        samlCallbackHandler.setIssuerPassword("security");
+        
+        java.util.Map<String, Object> config = new java.util.TreeMap<String, Object>();
+        config.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
+        config.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
+        reqData.setMsgContext(config);
+        
+        final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        CustomHandler handler = new CustomHandler();
+        HandlerAction action = new HandlerAction(WSConstants.ST_SIGNED);
+        handler.send(
+            doc, 
+            reqData, 
+            Collections.singletonList(action),
+            true
+        );
+        if (LOG.isDebugEnabled()) {
+            String outputString = XMLUtils.PrettyDocumentToString(doc);
+            LOG.debug(outputString);
+        }
+        
+        verify(doc, callbackHandler);
+    }
+    
+    @org.junit.Test
+    public void testAssertionWithSignatureAction() throws Exception {
+        final WSSConfig cfg = WSSConfig.getNewInstance();
+        final RequestData reqData = new RequestData();
+        reqData.setWssConfig(cfg);
+        reqData.setUsername("wss40");
+        
+        CallbackHandler callbackHandler = new KeystoreCallbackHandler();
+        
+        SAML1CallbackHandler samlCallbackHandler = new SAML1CallbackHandler();
+        samlCallbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
+        samlCallbackHandler.setIssuer("www.example.com");
+        
+        java.util.Map<String, Object> config = new java.util.TreeMap<String, Object>();
+        config.put(WSHandlerConstants.SIG_PROP_FILE, "wss40.properties");
+        config.put(WSHandlerConstants.PW_CALLBACK_REF, callbackHandler);
+        config.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
+        config.put(WSHandlerConstants.SIGNATURE_PARTS, "{}{" + WSConstants.SAML_NS + "}Assertion;");
+        reqData.setMsgContext(config);
+        
+        final Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        CustomHandler handler = new CustomHandler();
+        List<HandlerAction> actions = new ArrayList<HandlerAction>();
+        actions.add(new HandlerAction(WSConstants.ST_UNSIGNED));
+        actions.add(new HandlerAction(WSConstants.SIGN));
+        handler.send(
+            doc, 
+            reqData, 
+            actions,
+            true
+        );
+        if (LOG.isDebugEnabled()) {
+            String outputString = XMLUtils.PrettyDocumentToString(doc);
+            LOG.debug(outputString);
+        }
+        
+        verify(doc, callbackHandler);
+    }
+    
+    private List<WSSecurityEngineResult> verify(
+        Document doc, CallbackHandler callbackHandler
+    ) throws Exception {
+        List<WSSecurityEngineResult> results = 
+            secEngine.processSecurityHeader(doc, null, callbackHandler, crypto);
+        String outputString = 
+            XMLUtils.PrettyDocumentToString(doc);
+        assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
+        return results;
+    }
+    
+}

Modified: webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/resourceResolvers/ResolverSameDocument.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/resourceResolvers/ResolverSameDocument.java?rev=1567601&r1=1567600&r2=1567601&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/resourceResolvers/ResolverSameDocument.java (original)
+++ webservices/wss4j/trunk/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/resourceResolvers/ResolverSameDocument.java Wed Feb 12 11:41:00 2014
@@ -45,6 +45,16 @@ public class ResolverSameDocument extend
         if (attribute != null && attribute.getValue().equals(getId())) {
             return true;
         }
+        
+        attribute = xmlSecStartElement.getAttributeByName(WSSConstants.ATT_NULL_AssertionID);
+        if (attribute != null && attribute.getValue().equals(getId())) {
+            return true;
+        }
+        
+        attribute = xmlSecStartElement.getAttributeByName(WSSConstants.ATT_NULL_ID);
+        if (attribute != null && attribute.getValue().equals(getId())) {
+            return true;
+        }
         return super.matches(xmlSecStartElement);
     }
 }