Author: coheigea
Date: Wed Jan  7 04:34:41 2009
New Revision: 732321

URL: http://svn.apache.org/viewvc?rev=732321&view=rev
Log:
[WSS-154] - A fix for this issue + tests
 - The problem was that a custom processor or action could only be specified 
via a String
   corresponding to the classname, which was only instantiated when 
getProcessor/getAction was
   called. This is inconvenient if e.g. the object in question is to be 
spring-loaded.
 - I took a different solution to the proposed patch. The processor map in 
WSSConfig can now be
   considered as <String, String> or <String,Processor> (similarly for the 
action map). When
   getProcessor(QName) is called, if the object in the Map is a processor it's 
simply returned, if
   it's a String, it gets classloaded etc. This is fully backwards compatible. 
 - So to use a custom processor instance, you can just do e.g.:
        WSSConfig cfg = WSSConfig.getNewInstance();
        cfg.setProcessor(WSSecurityEngine.SIGNATURE, new wssec.MyProcessor());
        final WSSecurityEngine engine = new WSSecurityEngine();
        engine.setWssConfig(cfg);
        engine.processSecurityHeader(....)


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/TestWSSecurityUserProcessor.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=732321&r1=732320&r2=732321&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java (original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSSConfig.java Wed Jan  
7 04:34:41 2009
@@ -170,7 +170,7 @@
 
     /**
      * Set the timestamp precision mode. If set to <code>true</code> then use
-     * timestamps with milliseconds, otherwise omit the millisconds. As per XML
+     * timestamps with milliseconds, otherwise omit the milliseconds. As per 
XML
      * Date/Time specification the default is to include the milliseconds.
      */
     protected boolean precisionInMilliSeconds = true;
@@ -198,14 +198,16 @@
     protected HashMap jceProvider = new HashMap(10);
 
     /**
-     * The known actions.  These are initialized from a set of defaults,
-     * but the list may be modified via the setAction operation.
+     * The known actions. This map is of the form <Integer, String> or 
<Integer, Action>. 
+     * The known actions are initialized from a set of defaults,
+     * but the list may be modified via the setAction operations.
      */
     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.
+     * The known processors. This map is of the form <String, String> or 
<String,Processor>.
+     * The known processors are initialized from a set of defaults,
+     * but the list may be modified via the setProcessor operations.
      */
     private final java.util.Map processorMap = new 
java.util.HashMap(DEFAULT_PROCESSORS);
     
@@ -220,7 +222,7 @@
     
     /**
      * a boolean flag to record whether we have already been statically
-     * initialized.  This flag prevents repeated and unecessary calls
+     * initialized.  This flag prevents repeated and unnecessary calls
      * to static initialization code at construction time.
      */
     private static boolean staticallyInitialized = false;
@@ -273,8 +275,7 @@
      *         {...@link #getDefaultWSConfig getDefaultWSConfig()})
      */
     public static WSSConfig getNewInstance() {
-        WSSConfig config = new WSSConfig();
-        return config;
+        return new WSSConfig();
     }
 
     /**
@@ -374,13 +375,35 @@
     }
     
     /**
-     * Associate an action with a specific action code.
+     * Associate an action name with a specific action code.
      *
      * This operation allows applications to supply their own
      * actions for well-known operations.
      */
     public String setAction(int code, String action) {
-        return (String) actionMap.put(new Integer(code), action);
+        Object previousAction = actionMap.put(new Integer(code), action);
+        if (previousAction instanceof String) {
+            return (String)previousAction;
+        } else if (previousAction instanceof Action){
+            return previousAction.getClass().getName();
+        }
+        return null;
+    }
+    
+    /**
+     * Associate an action instance with a specific action code.
+     *
+     * This operation allows applications to supply their own
+     * actions for well-known operations.
+     */
+    public String setAction(int code, Action action) {
+        Object previousAction = actionMap.put(new Integer(code), action);
+        if (previousAction instanceof String) {
+            return (String)previousAction;
+        } else if (previousAction instanceof Action){
+            return previousAction.getClass().getName();
+        }
+        return null;
     }
 
     /**
@@ -392,20 +415,23 @@
      */
     public Action getAction(int action) throws WSSecurityException {
         Integer key = new Integer(action);
-        String name = (String) actionMap.get(key);
-        if (name == null) {
-            throw new WSSecurityException(WSSecurityException.FAILURE,
-                    "unknownAction", new Object[] { key });
-        }
-        try {
-            return (Action) Loader.loadClass(name).newInstance();
-        } catch (Throwable t) {
-            if (log.isDebugEnabled()) {
-                log.debug(t.getMessage(), t);
+        final Object actionObject = actionMap.get(key);
+        
+        if (actionObject instanceof String) {
+            final String name = (String)actionObject;
+            try {
+                return (Action) Loader.loadClass(name).newInstance();
+            } catch (Throwable t) {
+                if (log.isDebugEnabled()) {
+                    log.debug(t.getMessage(), t);
+                }
+                throw new WSSecurityException(WSSecurityException.FAILURE,
+                        "unableToLoadClass", new Object[] { name }, t);
             }
-            throw new WSSecurityException(WSSecurityException.FAILURE,
-                    "unableToLoadClass", new Object[] { name }, t);
-        }
+        } else if (actionObject instanceof Action) {
+            return (Action)actionObject;
+        } 
+        return null;
     }
     
     /**
@@ -414,7 +440,28 @@
      * called when processing header elements with the specified type.
      */
     public String setProcessor(QName el, String name) {
-        return (String) processorMap.put(el, name);
+        Object previousProcessor = processorMap.put(el, name);
+        if (previousProcessor instanceof String) {
+            return (String)previousProcessor;
+        } else if (previousProcessor instanceof Processor){
+            return previousProcessor.getClass().getName();
+        }
+        return null;
+    }
+    
+    /**
+     * Associate a SOAP processor instance 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 String setProcessor(QName el, Processor processor) {
+        Object previousProcessor = processorMap.put(el, processor);
+        if (previousProcessor instanceof String) {
+            return (String)previousProcessor;
+        } else if (previousProcessor instanceof Processor){
+            return previousProcessor.getClass().getName();
+        }
+        return null;
     }
 
     /**
@@ -425,8 +472,9 @@
      *              specified QName.
      */
     public Processor getProcessor(QName el) throws WSSecurityException {
-        final String name = (String) processorMap.get(el);
-        if (name != null) {
+        final Object processorObject = processorMap.get(el);
+        if (processorObject instanceof String) {
+            final String name = (String)processorObject;
             try {
                 return (Processor) Loader.loadClass(name).newInstance();
             } catch (Throwable t) {
@@ -436,7 +484,9 @@
                 throw new WSSecurityException(WSSecurityException.FAILURE,
                         "unableToLoadClass", new Object[] { name }, t);
             }
-        }
+        } else if (processorObject instanceof Processor) {
+            return (Processor)processorObject;
+        } 
         return null;
     }
 

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=732321&r1=732320&r2=732321&view=diff
==============================================================================
--- webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java 
(original)
+++ webservices/wss4j/trunk/src/org/apache/ws/security/WSSecurityEngine.java 
Wed Jan  7 04:34:41 2009
@@ -58,62 +58,76 @@
     /**
      * <code>wsse:BinarySecurityToken</code> as defined by WS Security 
specification
      */
-    public static final QName binaryToken = new QName(WSConstants.WSSE_NS, 
WSConstants.BINARY_TOKEN_LN);
+    public static final QName binaryToken = 
+        new QName(WSConstants.WSSE_NS, WSConstants.BINARY_TOKEN_LN);
     /**
      * <code>wsse:UsernameToken</code> as defined by WS Security specification
      */
-    public static final QName usernameToken = new QName(WSConstants.WSSE_NS, 
WSConstants.USERNAME_TOKEN_LN);
+    public static final QName usernameToken = 
+        new QName(WSConstants.WSSE_NS, WSConstants.USERNAME_TOKEN_LN);
     /**
      * <code>wsu:Timestamp</code> as defined by OASIS WS Security 
specification,
      */
-    public static final QName timeStamp = new QName(WSConstants.WSU_NS, 
WSConstants.TIMESTAMP_TOKEN_LN);
+    public static final QName timeStamp = 
+        new QName(WSConstants.WSU_NS, WSConstants.TIMESTAMP_TOKEN_LN);
     /**
      * <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
      */
-    public static final QName SIGNATURE = new QName(WSConstants.SIG_NS, 
WSConstants.SIG_LN);
+    public static final QName SIGNATURE = 
+        new QName(WSConstants.SIG_NS, WSConstants.SIG_LN);
     /**
      * <code>xenc:EncryptedKey</code> as defined by XML Encryption 
specification,
      * enhanced by WS Security specification
      */
-    public static final QName ENCRYPTED_KEY = new QName(WSConstants.ENC_NS, 
WSConstants.ENC_KEY_LN);
+    public static final QName ENCRYPTED_KEY = 
+        new QName(WSConstants.ENC_NS, WSConstants.ENC_KEY_LN);
     /**
      * <code>xenc:EncryptedData</code> as defined by XML Encryption 
specification,
      * enhanced by WS Security specification
      */
-    public static final QName ENCRYPTED_DATA = new QName(WSConstants.ENC_NS, 
WSConstants.ENC_DATA_LN);
+    public static final QName ENCRYPTED_DATA = 
+        new QName(WSConstants.ENC_NS, WSConstants.ENC_DATA_LN);
     /**
      * <code>xenc:ReferenceList</code> as defined by XML Encryption 
specification,
      */
-    public static final QName REFERENCE_LIST = new QName(WSConstants.ENC_NS, 
WSConstants.REF_LIST_LN);
+    public static final QName REFERENCE_LIST = 
+        new QName(WSConstants.ENC_NS, WSConstants.REF_LIST_LN);
     /**
      * <code>saml:Assertion</code> as defined by SAML specification
      */
-    public static final QName SAML_TOKEN = new QName(WSConstants.SAML_NS, 
WSConstants.ASSERTION_LN);
+    public static final QName SAML_TOKEN = 
+        new QName(WSConstants.SAML_NS, WSConstants.ASSERTION_LN);
 
     /**
      * <code>wsc:DerivedKeyToken</code> as defined by WS-SecureConversation 
specification
      */
-    public static final QName DERIVED_KEY_TOKEN_05_02 = new 
QName(ConversationConstants.WSC_NS_05_02, 
ConversationConstants.DERIVED_KEY_TOKEN_LN);
+    public static final QName DERIVED_KEY_TOKEN_05_02 = 
+        new QName(ConversationConstants.WSC_NS_05_02, 
ConversationConstants.DERIVED_KEY_TOKEN_LN);
 
     /**
      * <code>wsc:SecurityContextToken</code> as defined by 
WS-SecureConversation specification
      */
-    public static final QName SECURITY_CONTEXT_TOKEN_05_02 = new 
QName(ConversationConstants.WSC_NS_05_02, 
ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+    public static final QName SECURITY_CONTEXT_TOKEN_05_02 = 
+        new QName(ConversationConstants.WSC_NS_05_02, 
ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
 
     /**
      * <code>wsc:DerivedKeyToken</code> as defined by WS-SecureConversation 
specification in WS-SX
      */
-    public static final QName DERIVED_KEY_TOKEN_05_12 = new 
QName(ConversationConstants.WSC_NS_05_12, 
ConversationConstants.DERIVED_KEY_TOKEN_LN);
+    public static final QName DERIVED_KEY_TOKEN_05_12 = 
+        new QName(ConversationConstants.WSC_NS_05_12, 
ConversationConstants.DERIVED_KEY_TOKEN_LN);
 
     /**
-     * <code>wsc:SecurityContextToken</code> as defined by 
WS-SecureConversation specification in WS-SX
+     * <code>wsc:SecurityContextToken</code> as defined by 
WS-SecureConversation specification in 
+     * WS-SX
      */
-    public static final QName SECURITY_CONTEXT_TOKEN_05_12 = new 
QName(ConversationConstants.WSC_NS_05_12, 
ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
+    public static final QName SECURITY_CONTEXT_TOKEN_05_12 = 
+        new QName(ConversationConstants.WSC_NS_05_12, 
ConversationConstants.SECURITY_CONTEXT_TOKEN_LN);
     
     public WSSecurityEngine() {
     }
@@ -171,7 +185,8 @@
      *               handling of certificates.
      * @return a result vector
      * @throws WSSecurityException
-     * @see WSSecurityEngine#processSecurityHeader(Element securityHeader, 
CallbackHandler cb,Crypto sigCrypto, Crypto decCrypto)
+     * @see WSSecurityEngine#processSecurityHeader(Element securityHeader, 
CallbackHandler cb,
+     * Crypto sigCrypto, Crypto decCrypto)
      */
     public Vector processSecurityHeader(Document doc,
                                         String actor,
@@ -201,7 +216,7 @@
      * @return a result vector
      * @throws WSSecurityException
      * @see WSSecurityEngine#processSecurityHeader(
-     * Element securityHeader, CallbackHandler cb,Crypto sigCrypto, Crypto 
decCrypto)
+     * Element securityHeader, CallbackHandler cb, Crypto sigCrypto, Crypto 
decCrypto)
      */
     public Vector processSecurityHeader(Document doc,
                                         String actor,
@@ -223,8 +238,7 @@
         Element elem = WSSecurityUtil.getSecurityHeader(doc, actor, sc);
         if (elem != null) {
             if (doDebug) {
-                log.debug("Processing WS-Security header for '" + actor
-                        + "' actor.");
+                log.debug("Processing WS-Security header for '" + actor + "' 
actor.");
             }
             wsResult = processSecurityHeader(elem, cb, sigCrypto, decCrypto);
         }
@@ -313,20 +327,23 @@
                 wsDocInfo.setProcessor(p);
             } else {
                 /*
-                * Add check for a BinarySecurityToken, add info to WSDocInfo. 
If BST is
-                * found before a Signature token this would speed up (at least 
a little
-                * bit) the processing of STR Transform.
-                */
+                 * Add check for a BinarySecurityToken, add info to WSDocInfo. 
If BST is
+                 * found before a Signature token this would speed up (at 
least a little
+                 * bit) the processing of STR Transform.
+                 */
                 if (doDebug) {
-                    log.debug("Unknown Element: " + elem.getLocalName() + " " 
+ elem.getNamespaceURI());
+                    log.debug(
+                        "Unknown Element: " + elem.getLocalName() + " " + 
elem.getNamespaceURI()
+                    );
                 }
             }
         }
         if (tlog.isDebugEnabled()) {
             t2 = System.currentTimeMillis();
-            tlog.debug("processHeader: total " + (t2 - t0) +
-                    ", prepare " + (t1 - t0) +
-                    ", handle " + (t2 - t1));
+            tlog.debug(
+                "processHeader: total " + (t2 - t0) + ", prepare " + (t1 - t0) 
+                + ", handle " + (t2 - t1)
+            );
         }
         return returnResults;
     }

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=732321&r1=732320&r2=732321&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 
Wed Jan  7 04:34:41 2009
@@ -249,7 +249,10 @@
     protected void doReceiverAction(int doAction, RequestData reqData)
         throws WSSecurityException {
 
-        WSSConfig wssConfig = WSSConfig.getNewInstance();
+        WSSConfig wssConfig = reqData.getWssConfig();
+        if (wssConfig == null) {
+            wssConfig = WSSConfig.getNewInstance();
+        }
         wssConfig.setEnableSignatureConfirmation(
             decodeEnableSignatureConfirmation(reqData)
         );

Modified: webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java?rev=732321&r1=732320&r2=732321&view=diff
==============================================================================
--- webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java 
(original)
+++ webservices/wss4j/trunk/test/wssec/TestWSSecurityUserProcessor.java Wed Jan 
 7 04:34:41 2009
@@ -126,7 +126,7 @@
     }
 
     /**
-     * Test to see that a custom processor configured through a
+     * Test to see that a custom processor configured through a 
      * WSSConfig instance is called
      */
     public void 
@@ -142,7 +142,7 @@
 
         /*
          * convert the resulting document into a message first. The 
toSOAPMessage()
-         * mehtod performs the necessary c14n call to properly set up the 
signed
+         * method 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.
          */
@@ -185,6 +185,64 @@
     }
     
     /**
+     * Test to see that a custom processor (object) configured through a 
+     * WSSConfig instance is called
+     */
+    public void 
+    testCustomUserProcessorObject() 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()
+         * method 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();
+        cfg.setProcessor(
+            WSSecurityEngine.SIGNATURE,
+            new wssec.MyProcessor()
+        );
+        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.getClass().getName().equals(wssec.MyProcessor.class.getName())) {
+                    found = true;
+                }
+            }
+        }
+        assertTrue("Unable to find result from MyProcessor", found);
+    }
+    
+    /**
      * Test to see that a custom action configured through a
      * WSSConfig instance is called
      */
@@ -214,6 +272,35 @@
     }
     
     /**
+     * Test to see that a custom action object configured through a
+     * WSSConfig instance is called
+     */
+    public void
+    testCustomActionObject() throws Exception {
+        
+        final WSSConfig cfg = WSSConfig.getNewInstance();
+        final int action = 0xDEADF000;
+        cfg.setAction(action, new wssec.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();
+        reqData.setMsgContext("bread");
+        assertEquals(reqData.getMsgContext(), "bread");
+        handler.doit(
+            action, 
+            doc, 
+            reqData, 
+            actions
+        );
+        assertEquals(reqData.getMsgContext(), "crumb");
+    }
+    
+    /**
      * a trivial extension of the WSHandler type
      */
     public static class MyHandler extends WSHandler {



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to