Author: fadushin
Date: Fri Apr  4 13:00:52 2008
New Revision: 644869

URL: http://svn.apache.org/viewvc?rev=644869&view=rev
Log:
[WSS-74, WSS-56] Added ability to support custom processors

 * Modified WSSConfig object to support custom processors
 * Required some modifications to WSSConfig initialization semantics,
   to make it slightly lazier
 * Added ability to disable registration of JCE providers
   (defaults to existing behavior, for backwards compatibility)


Added:
    webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java   (with 
props)
Modified:
    webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java
    webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java
    webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java
    webservices/wss4j/trunk/test/wssec/PackageTests.java

Modified: webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java?rev=644869&r1=644868&r2=644869&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java Fri Apr  
4 13:00:52 2008
@@ -42,9 +42,158 @@
  * @author Werner Dittmann ([EMAIL PROTECTED])
  */
 public class WSSConfig {
+
+    /**
+     * The default collection of actions supported by the toolkit.
+     */
+    private static final java.util.Map DEFAULT_ACTIONS;
+    static {
+        final java.util.Map tmp = new java.util.HashMap();
+        try {
+            tmp.put(
+                new Integer(WSConstants.UT),
+                (Action) Loader.loadClass(
+                    
org.apache.ws.security.action.UsernameTokenAction.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                new Integer(WSConstants.ENCR),
+                (Action) Loader.loadClass(
+                    
org.apache.ws.security.action.EncryptionAction.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                new Integer(WSConstants.SIGN),
+                (Action) Loader.loadClass(
+                    
org.apache.ws.security.action.SignatureAction.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                new Integer(WSConstants.ST_SIGNED),
+                (Action) Loader.loadClass(
+                    
org.apache.ws.security.action.SAMLTokenSignedAction.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                new Integer(WSConstants.ST_UNSIGNED),
+                (Action) Loader.loadClass(
+                    
org.apache.ws.security.action.SAMLTokenUnsignedAction.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                new Integer(WSConstants.TS),
+                (Action) Loader.loadClass(
+                    
org.apache.ws.security.action.TimestampAction.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                new Integer(WSConstants.UT_SIGN),
+                (Action) Loader.loadClass(
+                    
org.apache.ws.security.action.UsernameTokenSignedAction.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                new Integer(WSConstants.SC),
+                (Action) Loader.loadClass(
+                    
org.apache.ws.security.action.SignatureConfirmationAction.class.getName()
+                ).newInstance()
+            );
+        } catch (final Throwable t) {
+            t.printStackTrace();
+        }
+        DEFAULT_ACTIONS = java.util.Collections.unmodifiableMap(tmp);
+    }
+
+    /**
+     * The default collection of processors supported by the toolkit
+     */
+    private static final java.util.Map DEFAULT_PROCESSORS;
+    static {
+        final java.util.Map tmp = new java.util.HashMap();
+        try {
+            tmp.put(
+                WSSecurityEngine.SAML_TOKEN,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.SAMLTokenProcessor.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                WSSecurityEngine.ENCRYPTED_KEY,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.EncryptedKeyProcessor.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                WSSecurityEngine.SIGNATURE,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.SignatureProcessor.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                WSSecurityEngine.timeStamp,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.TimestampProcessor.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                WSSecurityEngine.usernameToken,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.UsernameTokenProcessor.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                WSSecurityEngine.REFERENCE_LIST,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.ReferenceListProcessor.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                WSSecurityEngine.signatureConfirmation,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.SignatureConfirmationProcessor.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                WSSecurityEngine.DERIVED_KEY_TOKEN_05_02,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.DerivedKeyTokenProcessor.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                WSSecurityEngine.DERIVED_KEY_TOKEN_05_12,
+                tmp.get(WSSecurityEngine.DERIVED_KEY_TOKEN_05_02)
+            );
+            tmp.put(
+                WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_02,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.SecurityContextTokenProcessor.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_12,
+                tmp.get(WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_02)
+            );
+            tmp.put(
+                WSSecurityEngine.binaryToken,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.BinarySecurityTokenProcessor.class.getName()
+                ).newInstance()
+            );
+            tmp.put(
+                WSSecurityEngine.ENCRYPTED_DATA,
+                (Processor) Loader.loadClass(
+                    
org.apache.ws.security.processor.EncryptedDataProcessor.class.getName()
+                ).newInstance()
+            );
+        } catch (final Throwable t) {
+            t.printStackTrace();
+        }
+        DEFAULT_PROCESSORS = java.util.Collections.unmodifiableMap(tmp);
+    }
+
     private static Log log = LogFactory.getLog(WSSConfig.class.getName());
 
-    protected static WSSConfig defaultConfig = getNewInstance();
+    protected static WSSConfig defaultConfig = null;
 
     protected boolean wsiBSPCompliant = false;
 
@@ -68,24 +217,74 @@
 
     protected HashMap jceProvider = new HashMap(10);
 
-    protected WSSConfig() {
-        org.apache.xml.security.Init.init();
-        /*
-         * The last provider added has precedence, that is if JuiCE can be add
-         * then WSS4J uses this provider.
-         */
-        addJceProvider("BC",
-                "org.bouncycastle.jce.provider.BouncyCastleProvider");
-        addJceProvider("JuiCE",
-                "org.apache.security.juice.provider.JuiCEProviderOpenSSL");
-        Transform.init();
-        try {
-            Transform.register(STRTransform.implementedTransformURI,
-                    "org.apache.ws.security.transform.STRTransform");
-        } catch (Exception ex) {
+    /**
+     * The known actions.  These are initialized from a set of defaults,
+     * but the list may be modified via the setAction operation.
+     */
+    private final java.util.Map actionMap = new 
java.util.HashMap(DEFAULT_ACTIONS);
+
+    /**
+     * The known processors.  These are initialized from a set of defaults,
+     * but the list may be modified via the setProcessor operation.
+     */
+    private final java.util.Map processorMap = new 
java.util.HashMap(DEFAULT_PROCESSORS);
+    
+    /**
+     * a static boolean flag that determines whether default JCE providers
+     * should be added at the time of construction.
+     *
+     * These providers, and the order in which they are added, can interfere
+     * with some JVMs (such as IBMs).
+     */
+    private static boolean addJceProviders = true;
+    
+    /**
+     * a boolean flag to record whether we have already been statically
+     * initialized.  This flag prevents repeated and unecessary calls
+     * to static initialization code at construction time.
+     */
+    private static boolean staticallyInitialized = false;
+    
+    /**
+     * Set the value of the internal addJceProviders flag.  This flag
+     * turns on (or off) automatic registration of known JCE providers
+     * that provide necessary cryptographic algorithms for use with WSS4J.
+     * By default, this flag is true, for backwards compatibility.  You may
+     * wish (or need) to initialize the JCE manually, e.g., in some JVMs.
+     */
+    public static void setAddJceProviders(boolean value) {
+        addJceProviders = value;
+    }
+    
+    private synchronized void
+    staticInit() {
+        if (!staticallyInitialized) {
+            org.apache.xml.security.Init.init();
+            if (addJceProviders) {
+            /*
+             * The last provider added has precedence, that is if JuiCE can be 
add
+             * then WSS4J uses this provider.
+             */
+            addJceProvider("BC",
+                    "org.bouncycastle.jce.provider.BouncyCastleProvider");
+            addJceProvider("JuiCE",
+                    "org.apache.security.juice.provider.JuiCEProviderOpenSSL");
+            }
+            Transform.init();
+            try {
+                Transform.register(STRTransform.implementedTransformURI,
+                        "org.apache.ws.security.transform.STRTransform");
+            } catch (Exception ex) {
+                // TODO log error
+            }
+            staticallyInitialized = true;
         }
     }
-
+    
+    protected WSSConfig() {
+        staticInit();
+    }
+    
     /**
      * @return a new WSSConfig instance configured with the default values
      *         (values identical to
@@ -101,6 +300,9 @@
      * OASIS WS-Seurity settings.
      */
     public static WSSConfig getDefaultWSConfig() {
+        if (defaultConfig == null) {
+            defaultConfig = getNewInstance();
+        }
         return defaultConfig;
     }
 
@@ -173,6 +375,16 @@
     public void setTimeStampStrict(boolean timeStampStrict) {
         this.timeStampStrict = timeStampStrict;
     }
+    
+    /**
+     * Associate an action with a specific action code.
+     *
+     * This operation allows applications to supply their own
+     * actions for well-known operations.
+     */
+    public Action setAction(int code, Action action) {
+        return (Action) actionMap.put(new Integer(code), action);
+    }
 
     /**
      * Lookup action
@@ -182,88 +394,32 @@
      * @throws WSSecurityException
      */
     public Action getAction(int action) throws WSSecurityException {
-        String name = null;
-        switch (action) {
-        case WSConstants.UT:
-            name = "org.apache.ws.security.action.UsernameTokenAction";
-            break;
-
-        case WSConstants.ENCR:
-            name = "org.apache.ws.security.action.EncryptionAction";
-            break;
-
-        case WSConstants.SIGN:
-            name = "org.apache.ws.security.action.SignatureAction";
-            break;
-
-        case WSConstants.ST_SIGNED:
-            name = "org.apache.ws.security.action.SAMLTokenSignedAction";
-            break;
-
-        case WSConstants.ST_UNSIGNED:
-            name = "org.apache.ws.security.action.SAMLTokenUnsignedAction";
-            break;
-
-        case WSConstants.TS:
-            name = "org.apache.ws.security.action.TimestampAction";
-            break;
-
-        case WSConstants.UT_SIGN:
-            name = "org.apache.ws.security.action.UsernameTokenSignedAction";
-            break;
-        case WSConstants.SC:
-            name = "org.apache.ws.security.action.SignatureConfirmationAction";
-            break;
-        }
-        if (name == null) {
-            throw new WSSecurityException(WSSecurityException.FAILURE,
-                    "unknownAction", new Object[] { new Integer(action) });
-        }
-        try {
-            return (Action) Loader.loadClass(name).newInstance();
-        } catch (Throwable t) {
+        Integer key = new Integer(action);
+        Action ret = (Action) actionMap.get(key);
+        if (ret == null) {
             throw new WSSecurityException(WSSecurityException.FAILURE,
-                    "unableToLoadClass", new Object[] { name });
+                    "unknownAction", new Object[] { key });
         }
+        return ret;
+    }
+    
+    /**
+     * Associate a SOAP processor with a specified SOAP Security header
+     * element QName.  Processors registered under this QName will be
+     * called when processing header elements with the specified type.
+     */
+    public Processor setProcessor(QName el, Processor p) {
+        return (Processor) processorMap.put(el, p);
     }
 
+    /**
+     * @return      the SOAP processor associated with the specified
+     *              QName.  The QName is intended to refer to an element
+     *              in a SOAP security header.
+     */
     public Processor getProcessor(QName el) throws WSSecurityException {
-        String name = null;
-        if (el.equals(WSSecurityEngine.SAML_TOKEN)) {
-            name = "org.apache.ws.security.processor.SAMLTokenProcessor";
-        } else if (el.equals(WSSecurityEngine.ENCRYPTED_KEY)) {
-            name = "org.apache.ws.security.processor.EncryptedKeyProcessor";
-        } else if (el.equals(WSSecurityEngine.SIGNATURE)) {
-            name = "org.apache.ws.security.processor.SignatureProcessor";
-        } else if (el.equals(WSSecurityEngine.timeStamp)) {
-            name = "org.apache.ws.security.processor.TimestampProcessor";
-        } else if (el.equals(WSSecurityEngine.usernameToken)) {
-            name = "org.apache.ws.security.processor.UsernameTokenProcessor";
-        } else if (el.equals(WSSecurityEngine.REFERENCE_LIST)) {
-            name = "org.apache.ws.security.processor.ReferenceListProcessor";
-        } else if (el.equals(WSSecurityEngine.signatureConfirmation)) {
-            name = 
"org.apache.ws.security.processor.SignatureConfirmationProcessor";
-        } else if (el.equals(WSSecurityEngine.DERIVED_KEY_TOKEN_05_02) ||
-                el.equals(WSSecurityEngine.DERIVED_KEY_TOKEN_05_12)) {
-            name = "org.apache.ws.security.processor.DerivedKeyTokenProcessor";
-        } else if(el.equals(WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_02) ||
-                el.equals(WSSecurityEngine.SECURITY_CONTEXT_TOKEN_05_12)) {
-            name = 
"org.apache.ws.security.processor.SecurityContextTokenProcessor";
-        } else if(el.equals(WSSecurityEngine.binaryToken)) {
-            name = 
"org.apache.ws.security.processor.BinarySecurityTokenProcessor";
-        } else if(el.equals(WSSecurityEngine.ENCRYPTED_DATA)) {
-            name = "org.apache.ws.security.processor.EncryptedDataProcessor";
-        }
-
-        if (name != null) {
-            try {
-                return (Processor) Loader.loadClass(name).newInstance();
-            } catch (Throwable t) {
-                throw new WSSecurityException(WSSecurityException.FAILURE,
-                        "unableToLoadClass", new Object[] { name });
-            }
-        }
-        return null;
+        Processor p = (Processor) processorMap.get(el);
+        return p;
     }
 
     private boolean loadProvider(String id, String className) {

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java?rev=644869&r1=644868&r2=644869&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java 
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java 
Fri Apr  4 13:00:52 2008
@@ -48,7 +48,12 @@
             LogFactory.getLog("org.apache.ws.security.TIME");
 
     private static WSSecurityEngine engine = null;
-    private static WSSConfig wssConfig = WSSConfig.getDefaultWSConfig();
+    
+    /**
+     * The WSSConfig instance used by this SecurityEngine to
+     * find Processors for processing security headers
+     */
+    private WSSConfig wssConfig = null;
     private boolean doDebug = false;
     /**
      * <code>wsse:BinarySecurityToken</code> as defined by WS Security 
specification
@@ -65,7 +70,7 @@
     /**
      * <code>wsse11:signatureConfirmation</code> as defined by OASIS WS 
Security specification,
      */
-   public static final QName signatureConfirmation = new 
QName(WSConstants.WSSE11_NS, WSConstants.SIGNATURE_CONFIRMATION_LN);
+    public static final QName signatureConfirmation = new 
QName(WSConstants.WSSE11_NS, WSConstants.SIGNATURE_CONFIRMATION_LN);
     /**
      * <code>ds:Signature</code> as defined by XML Signature specification,
      * enhanced by WS Security specification
@@ -125,13 +130,30 @@
         }
         return engine;
     }
-
+    
     /**
-     * @param wsc set the static WSSConfig to other than default
+     * @return      the WSSConfig object set on this instance, or
+     *              the statically defined one, if the instance-level
+     *              config object is null.
+     */
+    public final WSSConfig
+    getWssConfig() {
+        return (wssConfig == null) ? WSSConfig.getDefaultWSConfig() : 
wssConfig;
+    }
+    
+    /**
+     * @param       the WSSConfig instance for this WSSecurityEngine to use
+     *
+     * @return      the WSSConfig instance previously set on this 
+     *              WSSecurityEngine instance
      */
-    public static void setWssConfig(WSSConfig wsc) {
-        wssConfig = wsc;
+    public final WSSConfig
+    setWssConfig(WSSConfig cfg) {
+        WSSConfig ret = wssConfig;
+        wssConfig = cfg;
+        return ret;
     }
+    
     /**
      * Process the security header given the soap envelope as W3C document.
      * <p/>
@@ -229,6 +251,10 @@
      * <li>[EMAIL PROTECTED] #timeStamp <code>wsu:Timestamp</code>}</li>
      * </ul>
      *
+     * Note that additional child elements can be processed if appropriate
+     * Processors have been registered with the WSSCondig instance set
+     * on this class.
+     *
      * @param securityHeader the <code>wsse:Security</code> header element
      * @param cb             a callback hander to the caller to resolve 
passwords during
      *                       encryption and [EMAIL PROTECTED] 
UsernameToken}handling
@@ -274,14 +300,15 @@
                 continue;
             }
             QName el = new QName(elem.getNamespaceURI(), elem.getLocalName());
-            Processor p = wssConfig.getProcessor(el);
+            final WSSConfig cfg = getWssConfig();
+            Processor p = cfg.getProcessor(el);
             /*
              * Call the processor for this token. After the processor returns, 
              * store it for later retrival. The token processor may store some
              * information about the processed token
              */
             if (p != null) {
-                p.handleToken((Element) elem, sigCrypto, decCrypto, cb, 
wsDocInfo, returnResults, wssConfig);
+                p.handleToken((Element) elem, sigCrypto, decCrypto, cb, 
wsDocInfo, returnResults, cfg);
                 wsDocInfo.setProcessor(p);
             } else {
                 /*

Modified: 
webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java?rev=644869&r1=644868&r2=644869&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java 
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/handler/WSHandler.java 
Fri Apr  4 13:00:52 2008
@@ -25,6 +25,7 @@
 import org.apache.ws.security.WSSecurityEngine;
 import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.action.Action;
 import org.apache.ws.security.components.crypto.Crypto;
 import org.apache.ws.security.components.crypto.CryptoFactory;
 import org.apache.ws.security.message.WSSecHeader;
@@ -83,7 +84,10 @@
 
         boolean mu = decodeMustUnderstand(reqData);
 
-        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        WSSConfig wssConfig = reqData.getWssConfig();
+        if (wssConfig == null) {
+            wssConfig = WSSConfig.getNewInstance();
+        }
         
         wssConfig
            
.setEnableSignatureConfirmation(decodeEnableSignatureConfirmation(reqData));
@@ -195,6 +199,24 @@
                 case WSConstants.NO_SERIALIZE:
                     reqData.setNoSerialization(true);
                     break;
+                //
+                // Handle any "custom" actions, similarly,
+                // but to preserve behavior from previous
+                // versions, consume (but log) action lookup failures.
+                //
+                default:
+                    Action doit = null;
+                    try {
+                        doit = wssConfig.getAction(actionToDo);
+                    } catch (final WSSecurityException e) {
+                        log.warn(
+                            "Error trying to locate a custom action (" + 
actionToDo + ")", 
+                            e
+                        );
+                    }
+                    if (doit != null) {
+                        doit.execute(this, actionToDo, doc, reqData);
+                    }
             }
         }
         /*

Modified: webservices/wss4j/trunk/test/wssec/PackageTests.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/PackageTests.java?rev=644869&r1=644868&r2=644869&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/PackageTests.java (original)
+++ webservices/wss4j/trunk/test/wssec/PackageTests.java Fri Apr  4 13:00:52 
2008
@@ -70,6 +70,7 @@
         suite.addTestSuite(TestWSSecurityNewST3.class);
         suite.addTestSuite(TestWSSecurityNewDK.class);
         suite.addTestSuite(TestWSSecurityNewSCT.class);
+        suite.addTestSuite(TestWSSecurityUserProcessor.class);
         return suite;
     }
 

Added: webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java?rev=644869&view=auto
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java (added)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java Fri Apr 
 4 13:00:52 2008
@@ -0,0 +1,314 @@
+/*
+ * Copyright  2003-2004 The Apache Software Foundation.
+ *
+ *  Licensed 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 wssec;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.axis.Message;
+import org.apache.axis.MessageContext;
+import org.apache.axis.client.AxisClient;
+import org.apache.axis.utils.XMLUtils;
+import org.apache.axis.configuration.NullProvider;
+import org.apache.axis.message.SOAPEnvelope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
+import org.apache.ws.security.action.Action;
+import org.apache.ws.security.components.crypto.Crypto;
+import org.apache.ws.security.components.crypto.CryptoBase;
+import org.apache.ws.security.components.crypto.CryptoFactory;
+import org.apache.ws.security.handler.WSHandler;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.message.WSSecSignature;
+import org.apache.ws.security.message.WSSecHeader;
+import org.apache.ws.security.processor.Processor;
+import org.w3c.dom.Document;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.PrintWriter;
+
+
+/**
+ * WS-Security Test Case
+ * <p/>
+ */
+public class TestWSSecurityUserProcessor extends TestCase {
+    private static Log log = 
LogFactory.getLog(TestWSSecurityUserProcessor.class);
+    static final String NS = "http://www.w3.org/2000/09/xmldsig#";;
+    static final String soapMsg = 
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
+        + "<SOAP-ENV:Envelope "
+        +   "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"; "
+        +   "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"; "
+        +   "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\";>" 
+        +   "<SOAP-ENV:Body>" 
+        +       "<add 
xmlns=\"http://ws.apache.org/counter/counter_port_type\";>" 
+        +           "<value xmlns=\"\">15</value>" 
+        +       "</add>" 
+        +   "</SOAP-ENV:Body>" 
+        + "</SOAP-ENV:Envelope>";
+
+    static final Crypto crypto = CryptoFactory.getInstance();
+
+    MessageContext msgContext;
+    SOAPEnvelope unsignedEnvelope;
+
+    /**
+     * TestWSSecurity constructor
+     * <p/>
+     * 
+     * @param name name of the test
+     */
+    public TestWSSecurityUserProcessor(String name) {
+        super(name);
+    }
+
+    /**
+     * JUnit suite
+     * <p/>
+     * 
+     * @return a junit test suite
+     */
+    public static Test suite() {
+        return new TestSuite(TestWSSecurityUserProcessor.class);
+    }
+
+    /**
+     * Main method
+     * <p/>
+     * 
+     * @param args command line args
+     */
+    public static void main(String[] args) {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Setup method
+     * <p/>
+     * 
+     * @throws java.lang.Exception Thrown when there is a problem in setup
+     */
+    protected void setUp() throws Exception {
+        AxisClient tmpEngine = new AxisClient(new NullProvider());
+        msgContext = new MessageContext(tmpEngine);
+        unsignedEnvelope = getSOAPEnvelope();
+    }
+
+    /**
+     * Constructs a soap envelope
+     * <p/>
+     * 
+     * @return soap envelope
+     * @throws java.lang.Exception if there is any problem constructing the 
soap envelope
+     */
+    protected SOAPEnvelope getSOAPEnvelope() throws Exception {
+        InputStream in = new ByteArrayInputStream(soapMsg.getBytes());
+        Message msg = new Message(in);
+        msg.setMessageContext(msgContext);
+        return msg.getSOAPEnvelope();
+    }
+
+    /**
+     * Test to see that a custom processor configured through a
+     * WSSConfig instance is called
+     */
+    public void 
+    testCustomUserProcessor() throws Exception {
+        WSSecSignature builder = new WSSecSignature();
+        builder.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e", 
"security");
+        builder.setKeyIdentifierType(WSConstants.ISSUER_SERIAL);
+        log.info("Before Signing IS....");
+        Document doc = unsignedEnvelope.getAsDocument();
+        WSSecHeader secHeader = new WSSecHeader();
+        secHeader.insertSecurityHeader(doc);
+        Document signedDoc = builder.build(doc, crypto, secHeader);
+
+        /*
+         * convert the resulting document into a message first. The 
toSOAPMessage()
+         * mehtod performs the necessary c14n call to properly set up the 
signed
+         * document and convert it into a SOAP message. After that we extract 
it
+         * as a document again for further processing.
+         */
+
+        if (log.isDebugEnabled()) {
+            log.debug("Signed message with IssuerSerial key identifier:");
+            XMLUtils.PrettyElementToWriter(signedDoc.getDocumentElement(), new 
PrintWriter(System.out));
+        }
+        Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);
+        if (log.isDebugEnabled()) {
+            log.debug("Signed message with IssuerSerial key identifier(1):");
+            
XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new 
PrintWriter(System.out));
+        }
+        signedDoc = signedMsg.getSOAPEnvelope().getAsDocument();
+        log.info("After Signing IS....");
+        //
+        // Check to make sure we can install/replace and use our own processor
+        //
+        WSSConfig cfg = WSSConfig.getNewInstance();
+        Processor p = new MyProcessor();
+        cfg.setProcessor(
+            WSSecurityEngine.SIGNATURE,
+            p
+        );
+        final WSSecurityEngine engine = new WSSecurityEngine();
+        engine.setWssConfig(cfg);
+        final java.util.List results = 
+            engine.processSecurityHeader(doc, null, null, crypto);
+        boolean found = false;
+        for (final java.util.Iterator pos = results.iterator();  
pos.hasNext(); ) {
+            final java.util.Map result = (java.util.Map) pos.next();
+            Object obj = result.get("foo");
+            if (obj != null) {
+                if (obj == p) {
+                    found = true;
+                }
+            }
+        }
+        assertTrue("Unable to find result from MyProcessor", found);
+    }
+    
+    /**
+     * Test to see that a custom action configured through a
+     * WSSConfig instance is called
+     */
+    public void
+    testCustomAction() throws Exception {
+        
+        final WSSConfig cfg = WSSConfig.getNewInstance();
+        final int action = 0xDEADF000;
+        final MyAction myAction = new MyAction();
+        cfg.setAction(action, myAction);
+        final RequestData reqData = new RequestData();
+        reqData.setWssConfig(cfg);
+        reqData.setMsgContext(new java.util.TreeMap());
+        
+        final java.util.Vector actions = new java.util.Vector();
+        actions.add(new Integer(action));
+        final Document doc = unsignedEnvelope.getAsDocument();
+        MyHandler handler = new MyHandler();
+        handler.doit(
+            action, 
+            doc, 
+            reqData, 
+            actions
+        );
+        assertTrue(myAction.getCalled() == 1);
+    }
+    
+    /**
+     * a custom processor that inserts itself into the results vector
+     */
+    private static class MyProcessor implements Processor {
+        
+        public final void 
+        handleToken(
+            org.w3c.dom.Element elem, 
+            org.apache.ws.security.components.crypto.Crypto crypto, 
+            org.apache.ws.security.components.crypto.Crypto decCrypto,
+            javax.security.auth.callback.CallbackHandler cb, 
+            org.apache.ws.security.WSDocInfo wsDocInfo, 
+            java.util.Vector returnResults,
+            org.apache.ws.security.WSSConfig config
+        ) throws org.apache.ws.security.WSSecurityException {
+            final java.util.Map result = 
+                new org.apache.ws.security.WSSecurityEngineResult(
+                    WSConstants.UT_SIGN, 
+                    
(org.apache.ws.security.message.token.SecurityContextToken) null
+                );
+            result.put("foo", this);
+            returnResults.add(result);
+        }
+
+        public final String getId() {
+            return getClass().getName();
+        }
+    }
+    
+    /**
+     * a custom action that counts how many times it's been called
+     */
+    private static class MyAction implements Action {
+        
+        private int called = 0;
+        
+        public void 
+        execute(
+            WSHandler handler, 
+            int actionToDo, 
+            Document doc,
+            RequestData reqData
+        ) throws org.apache.ws.security.WSSecurityException {
+            ++called;
+        }
+        
+        int getCalled(){ return called; }
+    }
+    
+    /**
+     * a trivial extension of the WSHandler type
+     */
+    private static class MyHandler extends WSHandler {
+        
+        public Object 
+        getOption(String key) {
+            return null;
+        }
+        
+        public void 
+        setProperty(
+            Object msgContext, 
+            String key, 
+            Object value
+        ) {
+        }
+
+        public Object 
+        getProperty(Object ctx, String key) {
+            return null;
+        }
+    
+        public void 
+        setPassword(Object msgContext, String password) {
+        }
+        
+        public String 
+        getPassword(Object msgContext) {
+            return null;
+        }
+
+        void doit(
+            int action, 
+            Document doc,
+            RequestData reqData, 
+            java.util.Vector actions
+        ) throws org.apache.ws.security.WSSecurityException {
+            doSenderAction(
+                action, 
+                doc, 
+                reqData, 
+                actions,
+                true
+            );
+        }
+    }
+}

Propchange: webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to