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 2014/07/11 20:30:31 UTC

[5/5] git commit: [CXF-5874] Add ability to turn on a strict Action checking

[CXF-5874] Add ability to turn on a strict Action checking


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/a4e4ea12
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/a4e4ea12
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/a4e4ea12

Branch: refs/heads/master
Commit: a4e4ea126e7f68d4f7c5de02aad5eaab50ac2a96
Parents: 3aa9adf
Author: Daniel Kulp <dk...@apache.org>
Authored: Fri Jul 11 14:03:24 2014 -0400
Committer: Daniel Kulp <dk...@apache.org>
Committed: Fri Jul 11 14:29:31 2014 -0400

----------------------------------------------------------------------
 .../interceptor/SoapActionInInterceptor.java    | 98 +++++++++++++++-----
 .../apache/cxf/ws/addressing/soap/MAPCodec.java |  5 +-
 .../sts/symmetric/SymmetricBindingTest.java     |  2 +-
 3 files changed, 82 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/a4e4ea12/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java
index b62c83b..8a257c7 100644
--- a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java
+++ b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java
@@ -46,6 +46,7 @@ public class SoapActionInInterceptor extends AbstractSoapInterceptor {
     
     private static final Logger LOG = LogUtils.getL7dLogger(SoapActionInInterceptor.class);
     private static final String ALLOW_NON_MATCHING_TO_DEFAULT = "allowNonMatchingToDefaultSoapAction";
+    private static final String CALCULATED_WSA_ACTION = SoapActionInInterceptor.class.getName() + ".ACTION";
     
     public SoapActionInInterceptor() {
         super(Phase.READ);
@@ -110,6 +111,9 @@ public class SoapActionInInterceptor extends AbstractSoapInterceptor {
     }
     
     public static void getAndSetOperation(SoapMessage message, String action) {
+        getAndSetOperation(message, action, true);
+    }
+    public static void getAndSetOperation(SoapMessage message, String action, boolean strict) {
         if (StringUtils.isEmpty(action)) {
             return;
         }
@@ -133,11 +137,7 @@ public class SoapActionInInterceptor extends AbstractSoapInterceptor {
                     }
                     bindingOp = boi;
                 }
-                Object o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME);
-                if (o == null) {
-                    o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME);
-                }
-                if (o != null && action.equals(o.toString())) {
+                if (matchWSAAction(boi, action)) {
                     if (bindingOp != null && bindingOp != boi) {
                         //more than one op with the same action, will need to parse normally
                         return;
@@ -148,44 +148,100 @@ public class SoapActionInInterceptor extends AbstractSoapInterceptor {
         }
         
         if (bindingOp == null) {
-            //we didn't match the an operation, we'll try again later to make
-            //sure the incoming message did end up matching an operation.
-            //This could occur in some cases like WS-RM and WS-SecConv that will
-            //intercept the message with a new endpoint/operation
-            message.getInterceptorChain().add(new SoapActionInAttemptTwoInterceptor());
+            if (strict) {
+                //we didn't match the an operation, we'll try again later to make
+                //sure the incoming message did end up matching an operation.
+                //This could occur in some cases like WS-RM and WS-SecConv that will
+                //intercept the message with a new endpoint/operation
+                message.getInterceptorChain().add(new SoapActionInAttemptTwoInterceptor(action));
+            }
             return;
         }
         
         ex.put(BindingOperationInfo.class, bindingOp);
         ex.put(OperationInfo.class, bindingOp.getOperationInfo());
     }
+    private static boolean matchWSAAction(BindingOperationInfo boi, String action) {
+        Object o = getWSAAction(boi);
+        if (o != null) {
+            String oa = o.toString();
+            if (action.equals(oa)
+                || action.equals(oa + "Request")
+                || oa.equals(action + "Request")) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    private static String getWSAAction(BindingOperationInfo boi) {
+        Object o = boi.getOperationInfo().getInput().getProperty(CALCULATED_WSA_ACTION);
+        if (o == null) {
+            o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME);
+            if (o == null) {
+                o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME);
+            }
+            if (o == null) {
+                String start = getActionBaseUri(boi.getOperationInfo());
+                if (null == boi.getOperationInfo().getInputName()) {
+                    o = addPath(start, boi.getOperationInfo().getName().getLocalPart());
+                } else {
+                    o = addPath(start, boi.getOperationInfo().getInputName());
+                }
+            }
+            if (o != null) {
+                boi.getOperationInfo().getInput().setProperty(CALCULATED_WSA_ACTION, o);
+            }
+        }
+        return o == null ? null : o.toString();
+    }
+    private static String getActionBaseUri(final OperationInfo operation) {
+        String interfaceName = operation.getInterface().getName().getLocalPart();
+        return addPath(operation.getName().getNamespaceURI(), interfaceName);
+    }
+    private static String getDelimiter(String uri) {
+        if (uri.startsWith("urn")) {
+            return ":";
+        }
+        return "/";
+    }
+
+    private static String addPath(String uri, String path) {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(uri);
+        String delimiter = getDelimiter(uri);
+        if (!uri.endsWith(delimiter) && !path.startsWith(delimiter)) {
+            buffer.append(delimiter);
+        }
+        buffer.append(path);
+        return buffer.toString();
+    }
+
     
     public static class SoapActionInAttemptTwoInterceptor extends AbstractSoapInterceptor {
-        public SoapActionInAttemptTwoInterceptor() {
-            super(Phase.PRE_LOGICAL);
+        final String action;
+        public SoapActionInAttemptTwoInterceptor(String action) {
+            super(action, Phase.PRE_LOGICAL);
+            this.action = action;
         }
         public void handleMessage(SoapMessage message) throws Fault {
             BindingOperationInfo boi = message.getExchange().getBindingOperationInfo();
             if (boi == null) {
                 return;
             }
-            String action = getSoapAction(message);
             if (StringUtils.isEmpty(action)) {
                 return;
             }
             if (isActionMatch(message, boi, action)) {
                 return;
             }
-
-            Object o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME);
-            if (o == null) {
-                o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME);
-            }
-            if (o != null && action.equals(o.toString())) {
+            if (matchWSAAction(boi, action)) {
                 return;
             }
-            
-            throw new Fault("SOAP_ACTION_MISMATCH", LOG, null, action);
+            boolean synthetic = Boolean.TRUE.equals(boi.getProperty("operation.is.synthetic"));
+            if (!synthetic) {
+                throw new Fault("SOAP_ACTION_MISMATCH", LOG, null, action);
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cxf/blob/a4e4ea12/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
----------------------------------------------------------------------
diff --git a/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java b/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
index bae8019..e0a5bf6 100644
--- a/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
+++ b/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
@@ -181,7 +181,10 @@ public class MAPCodec extends AbstractSoapInterceptor {
                     //try and use the Action from the maps to find the operation
                     String action = maps.getAction().getValue();
                     if (action != null) {
-                        SoapActionInInterceptor.getAndSetOperation(message, action);
+                        boolean strict = MessageUtils.getContextualBoolean(message, 
+                                                                           "ws-addressing.strict.action.checking", 
+                                                                           false);
+                        SoapActionInInterceptor.getAndSetOperation(message, action, strict);
                     }
                 }
             }

http://git-wip-us.apache.org/repos/asf/cxf/blob/a4e4ea12/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/symmetric/SymmetricBindingTest.java
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/symmetric/SymmetricBindingTest.java b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/symmetric/SymmetricBindingTest.java
index 9b232a5..3359cc9 100644
--- a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/symmetric/SymmetricBindingTest.java
+++ b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/symmetric/SymmetricBindingTest.java
@@ -261,7 +261,7 @@ public class SymmetricBindingTest extends AbstractBusClientServerTestBase {
         QName portQName = new QName(NAMESPACE, "DoubleItSymmetricSAML2Port");
        
         Dispatch<DOMSource> dispatch = 
-            service.createDispatch(portQName, DOMSource.class, Service.Mode.PAYLOAD);
+            service.createDispatch(portQName, DOMSource.class, Service.Mode.PAYLOAD, new AddressingFeature());
         updateAddressPort(dispatch, test.getPort());
         
         // Setup STSClient