This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/master by this push:
new ae7c3dc CXF-8010 - Avoid applying the SAAJInInterceptor to unsecured
messages when using WS-SecurityPolicy
ae7c3dc is described below
commit ae7c3dcfc7e70b8921f1c1c49734dc11ce0fde40
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Wed Apr 3 14:40:36 2019 +0100
CXF-8010 - Avoid applying the SAAJInInterceptor to unsecured messages when
using WS-SecurityPolicy
---
.../security/wss4j/AbstractWSS4JInterceptor.java | 4 ++
.../wss4j/PolicyBasedWSS4JInInterceptor.java | 77 +++++++++++++++++++++-
.../security/wss4j/AbstractPolicySecurityTest.java | 10 +++
.../ws/security/wss4j/AbstractSecurityTest.java | 8 +++
.../wss4j/PluggablePolicyValidatorTest.java | 11 ++++
.../security/wss4j/saml/PolicyBasedSamlTest.java | 13 ++++
.../ws/policy/operation/PolicyOperationTest.java | 2 +-
7 files changed, 123 insertions(+), 2 deletions(-)
diff --git
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JInterceptor.java
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JInterceptor.java
index e222faa..e72745f 100644
---
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JInterceptor.java
+++
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JInterceptor.java
@@ -99,6 +99,10 @@ public abstract class AbstractWSS4JInterceptor extends
WSHandler implements Soap
}
public Object getProperty(Object msgContext, String key) {
+ if (msgContext == null) {
+ return null;
+ }
+
Object obj = SecurityUtils.getSecurityPropertyValue(key,
(Message)msgContext);
if (obj == null) {
obj = getOption(key);
diff --git
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
index 2f054e4..767be4c 100644
---
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
+++
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/PolicyBasedWSS4JInInterceptor.java
@@ -21,17 +21,24 @@ package org.apache.cxf.ws.security.wss4j;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.logging.Logger;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.stream.XMLStreamException;
+import org.w3c.dom.Attr;
import org.w3c.dom.Element;
+import org.apache.cxf.binding.soap.SoapFault;
import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.MessageUtils;
@@ -44,6 +51,7 @@ import
org.apache.cxf.ws.security.wss4j.policyvalidators.PolicyValidatorParamete
import
org.apache.cxf.ws.security.wss4j.policyvalidators.SecurityPolicyValidator;
import org.apache.cxf.ws.security.wss4j.policyvalidators.ValidatorUtils;
import org.apache.wss4j.common.ConfigurationConstants;
+import org.apache.wss4j.common.WSS4JConstants;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.PasswordEncryptor;
import org.apache.wss4j.common.ext.WSSecurityException;
@@ -53,6 +61,7 @@ import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
import org.apache.wss4j.dom.handler.RequestData;
import org.apache.wss4j.dom.handler.WSHandlerResult;
import org.apache.wss4j.dom.message.token.Timestamp;
+import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.apache.wss4j.policy.SP12Constants;
import org.apache.wss4j.policy.SP13Constants;
import org.apache.wss4j.policy.SPConstants;
@@ -65,6 +74,9 @@ import org.apache.wss4j.policy.model.Wss11;
*
*/
public class PolicyBasedWSS4JInInterceptor extends WSS4JInInterceptor {
+
+ private static final Logger LOG =
LogUtils.getL7dLogger(PolicyBasedWSS4JInInterceptor.class);
+
/**
*
*/
@@ -76,11 +88,73 @@ public class PolicyBasedWSS4JInInterceptor extends
WSS4JInInterceptor {
AssertionInfoMap aim = msg.get(AssertionInfoMap.class);
boolean enableStax =
MessageUtils.getContextualBoolean(msg,
SecurityConstants.ENABLE_STREAMING_SECURITY);
- if (aim != null && !enableStax) {
+ if (aim != null && !enableStax && !msg.containsKey(SECURITY_PROCESSED)
+ && !isGET(msg) && msg.getExchange() != null) {
+ try {
+ // First check to see if we have a security header before we
apply the SAAJInInterceptor
+ // If there is no security header then we can just assert the
policies and proceed
+ String actor = (String)getOption(ConfigurationConstants.ACTOR);
+ if (actor == null) {
+ actor =
(String)msg.getContextualProperty(SecurityConstants.ACTOR);
+ }
+ if (!containsSecurityHeader(msg, actor,
msg.getVersion().getVersion() != 1.1)) {
+ LOG.fine("The request contains no security header, so the
SAAJInInterceptor is not applied");
+ computeAction(msg, new RequestData());
+
+ boolean utWithCallbacks =
+ MessageUtils.getContextualBoolean(msg,
SecurityConstants.VALIDATE_TOKEN, true);
+ doResults(msg, actor,
+ null,
+ null,
+ new WSHandlerResult(actor,
Collections.emptyList(), Collections.emptyMap()),
+ utWithCallbacks);
+ msg.put(SECURITY_PROCESSED, Boolean.TRUE);
+ return;
+ }
+ } catch (WSSecurityException e) {
+ throw WSS4JUtils.createSoapFault(msg, msg.getVersion(), e);
+ } catch (XMLStreamException e) {
+ throw new SoapFault(new Message("STAX_EX", LOG), e,
msg.getVersion().getSender());
+ } catch (SOAPException e) {
+ throw new SoapFault(new Message("SAAJ_EX", LOG), e,
msg.getVersion().getSender());
+ }
+
+
super.handleMessage(msg);
}
}
+ private boolean containsSecurityHeader(SoapMessage message, String actor,
boolean soap12)
+ throws WSSecurityException {
+ String actorLocal = WSConstants.ATTR_ACTOR;
+ String soapNamespace = WSConstants.URI_SOAP11_ENV;
+ if (soap12) {
+ actorLocal = WSConstants.ATTR_ROLE;
+ soapNamespace = WSConstants.URI_SOAP12_ENV;
+ }
+
+ //
+ // Iterate through the security headers
+ //
+ for (Header h : message.getHeaders()) {
+ QName n = h.getName();
+ if (WSConstants.WSSE_LN.equals(n.getLocalPart())
+ && (n.getNamespaceURI().equals(WSS4JConstants.WSSE_NS)
+ ||
n.getNamespaceURI().equals(WSS4JConstants.OLD_WSSE_NS))) {
+
+ Element elem = (Element)h.getObject();
+ Attr attr = elem.getAttributeNodeNS(soapNamespace, actorLocal);
+ String hActor = (attr != null) ? attr.getValue() : null;
+
+ if (WSSecurityUtil.isActorEqual(actor, hActor)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
private void handleWSS11(AssertionInfoMap aim, SoapMessage message) {
if (isRequestor(message)) {
message.put(ConfigurationConstants.ENABLE_SIGNATURE_CONFIRMATION,
"false");
@@ -383,6 +457,7 @@ public class PolicyBasedWSS4JInInterceptor extends
WSS4JInInterceptor {
}
}
+ @Override
protected void computeAction(SoapMessage message, RequestData data) throws
WSSecurityException {
String action = getString(ConfigurationConstants.ACTION, message);
if (action == null) {
diff --git
a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/AbstractPolicySecurityTest.java
b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/AbstractPolicySecurityTest.java
index ba15034..9246a1b 100644
---
a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/AbstractPolicySecurityTest.java
+++
b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/AbstractPolicySecurityTest.java
@@ -43,6 +43,7 @@ import org.w3c.dom.NodeList;
import org.apache.cxf.Bus;
import org.apache.cxf.BusException;
import org.apache.cxf.binding.Binding;
+import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.feature.Feature;
@@ -76,6 +77,7 @@ import org.apache.wss4j.dom.WSDataRef;
import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
import org.apache.wss4j.dom.handler.WSHandlerConstants;
import org.apache.wss4j.dom.handler.WSHandlerResult;
+import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.apache.wss4j.policy.SP12Constants;
import static org.junit.Assert.assertEquals;
@@ -263,6 +265,14 @@ public abstract class AbstractPolicySecurityTest extends
AbstractSecurityTest {
SoapMessage inmsg = this.getSoapMessageForDom(document, aim);
+ Element securityHeaderElem =
WSSecurityUtil.getSecurityHeader(document, "");
+ if (securityHeaderElem != null) {
+ SoapHeader securityHeader = new SoapHeader(new
QName(securityHeaderElem.getNamespaceURI(),
+
securityHeaderElem.getLocalName()),
+ securityHeaderElem);
+ inmsg.getHeaders().add(securityHeader);
+ }
+
inHandler.handleMessage(inmsg);
for (CoverageType type : types) {
diff --git
a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/AbstractSecurityTest.java
b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/AbstractSecurityTest.java
index e622ba7..a39c672 100644
---
a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/AbstractSecurityTest.java
+++
b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/AbstractSecurityTest.java
@@ -25,6 +25,7 @@ import java.io.InputStream;
import java.util.List;
import java.util.Map;
+import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -36,8 +37,10 @@ import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import org.apache.cxf.binding.soap.Soap11;
+import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.saaj.SAAJStreamWriter;
import org.apache.cxf.helpers.DOMUtils.NullResolver;
@@ -48,6 +51,7 @@ import org.apache.cxf.phase.PhaseInterceptor;
import org.apache.cxf.staxutils.StaxUtils;
import org.apache.cxf.test.AbstractCXFTest;
import org.apache.wss4j.common.WSS4JConstants;
+import org.apache.wss4j.dom.util.WSSecurityUtil;
public abstract class AbstractSecurityTest extends AbstractCXFTest {
@@ -152,6 +156,10 @@ public abstract class AbstractSecurityTest extends
AbstractCXFTest {
ex.setInMessage(inmsg);
inmsg.setContent(SOAPMessage.class, saajMsg);
+ Element securityHeaderElem = WSSecurityUtil.getSecurityHeader(doc, "");
+ SoapHeader securityHeader = new SoapHeader(new
QName(securityHeaderElem.getNamespaceURI(),
+
securityHeaderElem.getLocalName()), securityHeaderElem);
+ inmsg.getHeaders().add(securityHeader);
inHandler.handleMessage(inmsg);
diff --git
a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/PluggablePolicyValidatorTest.java
b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/PluggablePolicyValidatorTest.java
index 1f55398..c84ef8c 100644
---
a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/PluggablePolicyValidatorTest.java
+++
b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/PluggablePolicyValidatorTest.java
@@ -27,7 +27,9 @@ import java.util.Map;
import javax.xml.namespace.QName;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.ws.policy.AssertionInfo;
import org.apache.cxf.ws.policy.AssertionInfoMap;
@@ -37,6 +39,7 @@ import
org.apache.cxf.ws.security.wss4j.CryptoCoverageUtil.CoverageType;
import
org.apache.cxf.ws.security.wss4j.policyvalidators.PolicyValidatorParameters;
import
org.apache.cxf.ws.security.wss4j.policyvalidators.SecurityPolicyValidator;
import org.apache.neethi.Policy;
+import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.apache.wss4j.policy.SP12Constants;
import org.junit.Test;
@@ -133,6 +136,14 @@ public class PluggablePolicyValidatorTest extends
AbstractPolicySecurityTest {
SoapMessage inmsg = this.getSoapMessageForDom(document, aim);
+ Element securityHeaderElem =
WSSecurityUtil.getSecurityHeader(document, "");
+ if (securityHeaderElem != null) {
+ SoapHeader securityHeader = new SoapHeader(new
QName(securityHeaderElem.getNamespaceURI(),
+
securityHeaderElem.getLocalName()),
+ securityHeaderElem);
+ inmsg.getHeaders().add(securityHeader);
+ }
+
if (validators != null) {
inmsg.put(SecurityConstants.POLICY_VALIDATOR_MAP, validators);
}
diff --git
a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/PolicyBasedSamlTest.java
b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/PolicyBasedSamlTest.java
index c7207bf..506115b 100644
---
a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/PolicyBasedSamlTest.java
+++
b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/saml/PolicyBasedSamlTest.java
@@ -22,14 +22,19 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import javax.xml.namespace.QName;
+
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.ws.policy.AssertionInfoMap;
import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.cxf.ws.security.wss4j.AbstractPolicySecurityTest;
import org.apache.cxf.ws.security.wss4j.CryptoCoverageUtil.CoverageType;
import org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor;
+import org.apache.wss4j.dom.util.WSSecurityUtil;
import org.apache.wss4j.dom.validate.SamlAssertionValidator;
import org.apache.wss4j.policy.SP12Constants;
@@ -115,6 +120,14 @@ public class PolicyBasedSamlTest extends
AbstractPolicySecurityTest {
SoapMessage inmsg = this.getSoapMessageForDom(document, aim);
+ Element securityHeaderElem =
WSSecurityUtil.getSecurityHeader(document, "");
+ if (securityHeaderElem != null) {
+ SoapHeader securityHeader = new SoapHeader(new
QName(securityHeaderElem.getNamespaceURI(),
+
securityHeaderElem.getLocalName()),
+ securityHeaderElem);
+ inmsg.getHeaders().add(securityHeader);
+ }
+
// Necessary because the Bearer Assertion does not have an internal
signature
SamlAssertionValidator assertionValidator = new
SamlAssertionValidator();
assertionValidator.setRequireBearerSignature(false);
diff --git
a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/policy/operation/PolicyOperationTest.java
b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/policy/operation/PolicyOperationTest.java
index 6dbf8da..3afec9a 100644
---
a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/policy/operation/PolicyOperationTest.java
+++
b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/policy/operation/PolicyOperationTest.java
@@ -103,7 +103,7 @@ public class PolicyOperationTest extends
AbstractBusClientServerTestBase {
service.getPort(portQName, DoubleItPortType2.class);
updateAddressPort(port, PORT);
- assertEquals(50, port.doubleIt(25));
+ assertEquals(50, port.doubleIt2(25));
((java.io.Closeable)port).close();
bus.shutdown(true);