You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2010/01/27 16:38:53 UTC

svn commit: r903690 - in /cxf/branches/2.2.x-fixes: ./ rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/ rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/

Author: dkulp
Date: Wed Jan 27 15:38:52 2010
New Revision: 903690

URL: http://svn.apache.org/viewvc?rev=903690&view=rev
Log:
Merged revisions 903445 via svnmerge from 
https://svn.apache.org/repos/asf/cxf/trunk

........
  r903445 | dkulp | 2010-01-26 16:56:52 -0500 (Tue, 26 Jan 2010) | 2 lines
  
  Support for allowing users to configure custom Wss4J action implementations
  in WSS4JOutInterceptor
........

Modified:
    cxf/branches/2.2.x-fixes/   (props changed)
    cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/Messages.properties
    cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java
    cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptorTest.java

Propchange: cxf/branches/2.2.x-fixes/
------------------------------------------------------------------------------
Binary property 'svnmerge-integrated' - no diff available.

Modified: cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/Messages.properties
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/Messages.properties?rev=903690&r1=903689&r2=903690&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/Messages.properties (original)
+++ cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/Messages.properties Wed Jan 27 15:38:52 2010
@@ -22,5 +22,6 @@
 # OutInterceptor error messages
 NO_SAAJ_DOC: No SOAPMessage DOM was found. Please enable the SAAJInInterceptor.
 NO_ACTION: No security action was defined.
+BAD_ACTION: An invalid action configuration was defined.
 NO_USERNAME: Empty username for specified action.
 SECURITY_FAILED: Security processing failed.

Modified: cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java?rev=903690&r1=903689&r2=903690&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java (original)
+++ cxf/branches/2.2.x-fixes/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java Wed Jan 27 15:38:52 2010
@@ -35,16 +35,27 @@
 import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
 import org.apache.cxf.common.i18n.Message;
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.CastUtils;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.phase.Phase;
 import org.apache.cxf.phase.PhaseInterceptor;
 import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSConfig;
 import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.action.Action;
 import org.apache.ws.security.handler.RequestData;
 import org.apache.ws.security.handler.WSHandlerConstants;
 import org.apache.ws.security.util.WSSecurityUtil;
 
 public class WSS4JOutInterceptor extends AbstractWSS4JInterceptor {
+    
+    /**
+     * Property name for a map of action IDs ({@link Integer}) to action
+     * class names.  Values can be either {@link String}) or Objects
+     * implementing {@link Action}.  
+     */
+    public static final String WSS4J_ACTION_MAP = "wss4j.action.map";
+    
     private static final Logger LOG = LogUtils
             .getL7dLogger(WSS4JOutInterceptor.class);
 
@@ -52,6 +63,7 @@
             .getL7dLogger(WSS4JOutInterceptor.class,
                           null,
                           WSS4JOutInterceptor.class.getName() + "-Time");
+        
     private WSS4JOutInterceptorInternal ending;
     private SAAJOutInterceptor saajOut = new SAAJOutInterceptor();
     private boolean mtomEnabled;
@@ -152,6 +164,15 @@
              * housekeeping.
              */
             try {
+                WSSConfig config = WSSConfig.getNewInstance();
+                reqData.setWssConfig(config);
+                
+                /*
+                 * Setup any custom actions first by processing the input properties
+                 * and reconfiguring the WSSConfig with the user defined properties.
+                 */
+                this.configureActions(mc, doDebug, version, config);
+                
                 /*
                  * Get the action first.
                  */
@@ -162,7 +183,7 @@
                             .getReceiver());
                 }
     
-                int doAction = WSSecurityUtil.decodeAction(action, actions);
+                int doAction = WSSecurityUtil.decodeAction(action, actions, config);
                 if (doAction == WSConstants.NO_SECURITY) {
                     return;
                 }
@@ -275,5 +296,48 @@
         public void handleFault(SoapMessage message) {
             //nothing
         }
+        
+        private void configureActions(SoapMessage mc, boolean doDebug,
+                SoapVersion version, WSSConfig config) {
+            
+            final Map<Integer, Object> actionMap = CastUtils.cast(
+                (Map<?, ?>)getProperty(mc, WSS4J_ACTION_MAP));
+            if (actionMap != null) {
+                for (Map.Entry<Integer, Object> entry : actionMap.entrySet()) {
+                    String removedAction = null;
+                    
+                    // Be defensive here since the cast above is slightly risky
+                    // with the handler config options not being strongly typed.
+                    try {
+                        if (entry.getValue() instanceof String) {
+                            removedAction = config.setAction(
+                                    entry.getKey().intValue(),
+                                    (String) entry.getValue());
+                        } else if (entry.getValue() instanceof Action) {
+                            removedAction = config.setAction(
+                                    entry.getKey().intValue(),
+                                    (Action) entry.getValue());
+                        } else {
+                            throw new SoapFault(new Message("BAD_ACTION", LOG), version
+                                    .getReceiver());
+                        }
+                    } catch (ClassCastException e) {
+                        throw new SoapFault(new Message("BAD_ACTION", LOG), version
+                                .getReceiver());
+                    }
+                    
+                    if (doDebug) {
+                        if (removedAction != null) {
+                            LOG.fine("Replaced Action: " + removedAction
+                                    + " with Action: " + entry.getValue()
+                                    + " for ID: " + entry.getKey());
+                        } else {
+                            LOG.fine("Added Action: " + entry.getValue()
+                                    + " with ID: " + entry.getKey());
+                        }
+                    }
+                }
+            }
+        }
     }
 }

Modified: cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptorTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptorTest.java?rev=903690&r1=903689&r2=903690&view=diff
==============================================================================
--- cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptorTest.java (original)
+++ cxf/branches/2.2.x-fixes/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptorTest.java Wed Jan 27 15:38:52 2010
@@ -18,18 +18,29 @@
  */
 package org.apache.cxf.ws.security.wss4j;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import javax.xml.soap.SOAPMessage;
 import javax.xml.soap.SOAPPart;
 
+import org.w3c.dom.Document;
+
+import org.apache.cxf.binding.soap.SoapFault;
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.ExchangeImpl;
 import org.apache.cxf.message.MessageImpl;
 import org.apache.cxf.phase.PhaseInterceptor;
 import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.action.UsernameTokenAction;
+import org.apache.ws.security.handler.RequestData;
+import org.apache.ws.security.handler.WSHandler;
 import org.apache.ws.security.handler.WSHandlerConstants;
 import org.junit.Test;
 
+
 /**
  * @author <a href="mailto:tsztelak@gmail.com">Tomasz Sztelak</a>
  */
@@ -62,7 +73,7 @@
         // Test to see that the plaintext password is used in the header
         assertValid("//wsse:Security/wsse:UsernameToken/wsse:Password[text()='myAliasPassword']", doc);
     }
-    
+        
     @Test
     public void testUsernameTokenDigest() throws Exception {
         SOAPMessage saaj = readSAAJDocument("wsse-request-clean.xml");
@@ -166,4 +177,69 @@
         assertValid("//wsse:Security", doc);
         assertValid("//wsse:Security/wsu:Timestamp", doc);
     }
+    
+    @Test
+    public void testCustomAction() throws Exception {
+        SOAPMessage saaj = readSAAJDocument("wsse-request-clean.xml");
+
+        WSS4JOutInterceptor ohandler = new WSS4JOutInterceptor();
+        PhaseInterceptor<SoapMessage> handler = ohandler.createEndingInterceptor();
+
+        SoapMessage msg = new SoapMessage(new MessageImpl());
+        Exchange ex = new ExchangeImpl();
+        ex.setInMessage(msg);
+
+        msg.setContent(SOAPMessage.class, saaj);
+        
+        CountingUsernameTokenAction action = new CountingUsernameTokenAction();
+        Map<Object, Object> customActions = new HashMap<Object, Object>(1);
+        customActions.put(WSConstants.UT, action);
+                
+        msg.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
+        msg.put(WSHandlerConstants.SIG_PROP_FILE, "META-INF/cxf/outsecurity.properties");
+        msg.put(WSHandlerConstants.USER, "username");
+        msg.put("password", "myAliasPassword");
+        msg.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
+        msg.put(WSS4JOutInterceptor.WSS4J_ACTION_MAP, customActions);
+        handler.handleMessage(msg);
+
+        SOAPPart doc = saaj.getSOAPPart();
+        assertValid("//wsse:Security", doc);
+        assertValid("//wsse:Security/wsse:UsernameToken", doc);
+        assertValid("//wsse:Security/wsse:UsernameToken/wsse:Username[text()='username']", doc);
+        // Test to see that the plaintext password is used in the header
+        assertValid("//wsse:Security/wsse:UsernameToken/wsse:Password[text()='myAliasPassword']", doc);
+        assertEquals(1, action.getExecutions());
+        
+        try {
+            customActions.put(WSConstants.UT, new Object());
+            handler.handleMessage(msg);
+        } catch (SoapFault e) {
+            assertEquals("An invalid action configuration was defined.", e.getMessage());
+        }
+        
+        try {
+            customActions.put(new Object(), action);
+            handler.handleMessage(msg);
+        } catch (SoapFault e) {
+            assertEquals("An invalid action configuration was defined.", e.getMessage());
+        }
+    }
+    
+    private static class CountingUsernameTokenAction extends UsernameTokenAction {
+
+        private int executions;
+        
+        @Override
+        public void execute(WSHandler handler, int actionToDo, Document doc,
+                RequestData reqData) throws WSSecurityException {
+            
+            this.executions++;
+            super.execute(handler, actionToDo, doc, reqData);
+        }
+
+        public int getExecutions() {
+            return this.executions;
+        }
+    }
 }