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 a64cd05 CXF-8015 - Support "security.signature.password" property to
configure a signature password for WS-Security/RS-Security
a64cd05 is described below
commit a64cd0582d788064b84343012510097566f26de9
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Tue Apr 9 11:40:31 2019 +0100
CXF-8015 - Support "security.signature.password" property to configure a
signature password for WS-Security/RS-Security
---
.../cxf/rs/security/common/RSSecurityUtils.java | 9 +--
.../org/apache/cxf/rs/security/saml/SAMLUtils.java | 4 +-
.../cxf/rs/security/xml/XmlSecOutInterceptor.java | 6 +-
.../cxf/rs/security/xml/XmlSigOutInterceptor.java | 4 +-
.../apache/cxf/rt/security/SecurityConstants.java | 5 ++
.../wss4j/AbstractWSS4JStaxInterceptor.java | 39 +++++++++----
.../ws/security/wss4j/SamlTokenInterceptor.java | 4 ++
.../cxf/ws/security/wss4j/WSS4JInInterceptor.java | 32 +++++++++++
.../policyhandlers/AbstractBindingBuilder.java | 18 +++++-
.../policyhandlers/TransportBindingHandler.java | 13 ++++-
.../jaxrs/security/xml/JAXRSXmlSecTest.java | 43 ++++++++++++++
.../ws/password/PasswordPropertiesTest.java | 33 +++++++++++
.../cxf/systest/ws/password/DoubleItPassword.wsdl | 65 ++++++++++++++++++++++
.../org/apache/cxf/systest/ws/password/server.xml | 13 +++++
14 files changed, 257 insertions(+), 31 deletions(-)
diff --git
a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/RSSecurityUtils.java
b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/RSSecurityUtils.java
index efa4ce6..e67a0a7 100644
---
a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/RSSecurityUtils.java
+++
b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/common/RSSecurityUtils.java
@@ -130,14 +130,15 @@ public final class RSSecurityUtils {
return userName;
}
- public static String getPassword(Message message, String userName,
- int type, Class<?> callingClass) throws
WSSecurityException {
+ public static String getSignaturePassword(Message message, String userName,
+ Class<?> callingClass) throws
WSSecurityException {
CallbackHandler handler = getCallbackHandler(message, callingClass);
if (handler == null) {
- return null;
+ // See if we have a signature password we can use here instead
+ return
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SIGNATURE_PASSWORD,
message);
}
- WSPasswordCallback[] cb = {new WSPasswordCallback(userName, type)};
+ WSPasswordCallback[] cb = {new WSPasswordCallback(userName,
WSPasswordCallback.SIGNATURE)};
try {
handler.handle(cb);
} catch (Exception e) {
diff --git
a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
index 52c8dd0..98aad71 100644
---
a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
+++
b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/SAMLUtils.java
@@ -36,7 +36,6 @@ import org.apache.cxf.rs.security.common.RSSecurityUtils;
import org.apache.cxf.rs.security.saml.assertion.Subject;
import org.apache.cxf.rt.security.SecurityConstants;
import org.apache.wss4j.common.crypto.Crypto;
-import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.apache.wss4j.common.saml.SAMLCallback;
import org.apache.wss4j.common.saml.SAMLUtil;
import org.apache.wss4j.common.saml.SamlAssertionWrapper;
@@ -151,8 +150,7 @@ public final class SAMLUtils {
}
String password =
- RSSecurityUtils.getPassword(message, user,
WSPasswordCallback.SIGNATURE,
- SAMLUtils.class);
+ RSSecurityUtils.getSignaturePassword(message, user,
SAMLUtils.class);
assertion.signAssertion(user, password, crypto, false,
samlCallback.getCanonicalizationAlgorithm(),
diff --git
a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecOutInterceptor.java
b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecOutInterceptor.java
index a035261..92d153e 100644
---
a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecOutInterceptor.java
+++
b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecOutInterceptor.java
@@ -50,7 +50,6 @@ import org.apache.cxf.rs.security.common.RSSecurityUtils;
import org.apache.cxf.rt.security.SecurityConstants;
import org.apache.cxf.rt.security.utils.SecurityUtils;
import org.apache.wss4j.common.crypto.Crypto;
-import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.util.KeyUtils;
import org.apache.xml.security.Init;
@@ -281,8 +280,7 @@ public class XmlSecOutInterceptor extends
AbstractPhaseInterceptor<Message> {
throw new Exception("User name is not available");
}
- String password =
- RSSecurityUtils.getPassword(message, user,
WSPasswordCallback.SIGNATURE, this.getClass());
+ String password = RSSecurityUtils.getSignaturePassword(message, user,
this.getClass());
X509Certificate[] issuerCerts =
RSSecurityUtils.getCertificates(crypto, user);
properties.setSignatureCerts(issuerCerts);
@@ -342,7 +340,7 @@ public class XmlSecOutInterceptor extends
AbstractPhaseInterceptor<Message> {
if (Boolean.TRUE.equals(sigProps.getSignatureOmitC14nTransform())) {
properties.setSignatureIncludeDigestTransform(false);
}
-
+
if (elementsToSign == null || elementsToSign.isEmpty()) {
LOG.fine("No Elements to sign are specified, so the entire request
is signed");
SecurePart securePart =
diff --git
a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
index 7fd9a79..2e35a62 100644
---
a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
+++
b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSigOutInterceptor.java
@@ -40,7 +40,6 @@ import org.apache.cxf.rs.security.common.CryptoLoader;
import org.apache.cxf.rs.security.common.RSSecurityUtils;
import org.apache.cxf.rt.security.SecurityConstants;
import org.apache.wss4j.common.crypto.Crypto;
-import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.xml.security.signature.XMLSignature;
import org.apache.xml.security.transforms.Transforms;
@@ -117,8 +116,7 @@ public class XmlSigOutInterceptor extends
AbstractXmlSecOutInterceptor {
throw new Exception("User name is not available");
}
- String password =
- RSSecurityUtils.getPassword(message, user,
WSPasswordCallback.SIGNATURE, this.getClass());
+ String password = RSSecurityUtils.getSignaturePassword(message, user,
this.getClass());
X509Certificate[] issuerCerts =
RSSecurityUtils.getCertificates(crypto, user);
diff --git
a/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java
b/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java
index 66b848a..5068a8f 100644
---
a/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java
+++
b/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java
@@ -68,6 +68,11 @@ public class SecurityConstants {
public static final String SIGNATURE_USERNAME =
"security.signature.username";
/**
+ * The user's password for signature when a {@link CALLBACK_HANDLER} is
not defined.
+ */
+ public static final String SIGNATURE_PASSWORD =
"security.signature.password";
+
+ /**
* The user's name for encryption. It is used as the alias name in the
keystore to get the user's public
* key for encryption. If this is not defined, then {@link USERNAME} is
used instead. If
* that is also not specified, it uses the the default alias set in the
properties file referenced by
diff --git
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JStaxInterceptor.java
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JStaxInterceptor.java
index 299efe0..96f2efd 100644
---
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JStaxInterceptor.java
+++
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/AbstractWSS4JStaxInterceptor.java
@@ -41,6 +41,7 @@ import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.SoapInterceptor;
import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
@@ -214,20 +215,36 @@ public abstract class AbstractWSS4JStaxInterceptor
implements SoapInterceptor,
// If we have a "password" but no CallbackHandler then construct one
- if (callbackHandler == null && getPassword(soapMessage) != null) {
+ if (callbackHandler == null) {
+ final boolean outbound = MessageUtils.isOutbound(soapMessage);
final String password = getPassword(soapMessage);
- callbackHandler = new CallbackHandler() {
-
- @Override
- public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
- for (Callback callback : callbacks) {
- if (callback instanceof WSPasswordCallback) {
- WSPasswordCallback wsPasswordCallback =
(WSPasswordCallback)callback;
- wsPasswordCallback.setPassword(password);
+ final String signatureUser =
+
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SIGNATURE_USERNAME,
soapMessage);
+ final String signaturePassword =
+
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SIGNATURE_PASSWORD,
soapMessage);
+
+ if (!(StringUtils.isEmpty(password) &&
StringUtils.isEmpty(signaturePassword))) {
+ callbackHandler = new CallbackHandler() {
+
+ @Override
+ public void handle(Callback[] callbacks) throws
IOException, UnsupportedCallbackException {
+ for (Callback callback : callbacks) {
+ if (callback instanceof WSPasswordCallback) {
+ WSPasswordCallback wsPasswordCallback =
(WSPasswordCallback)callback;
+
+ if (signaturePassword != null &&
wsPasswordCallback.getIdentifier() != null
+ &&
wsPasswordCallback.getIdentifier().equals(signatureUser)
+ && (outbound &&
wsPasswordCallback.getUsage() == WSPasswordCallback.SIGNATURE)
+ || (!outbound &&
wsPasswordCallback.getUsage() == WSPasswordCallback.DECRYPT)) {
+
wsPasswordCallback.setPassword(signaturePassword);
+ } else if (password != null) {
+ wsPasswordCallback.setPassword(password);
+ }
+ }
}
}
- }
- };
+ };
+ }
}
if (callbackHandler != null) {
diff --git
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/SamlTokenInterceptor.java
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/SamlTokenInterceptor.java
index fa5af24..dbcdb05 100644
---
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/SamlTokenInterceptor.java
+++
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/SamlTokenInterceptor.java
@@ -280,6 +280,10 @@ public class SamlTokenInterceptor extends
AbstractTokenInterceptor {
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.PASSWORD,
message);
if (StringUtils.isEmpty(password)) {
password =
+
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SIGNATURE_PASSWORD,
message);
+ }
+ if (StringUtils.isEmpty(password)) {
+ password =
getPassword(issuerName, token,
WSPasswordCallback.SIGNATURE, message);
}
}
diff --git
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
index 14528c4..ef9958e 100644
---
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
+++
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
@@ -18,6 +18,7 @@
*/
package org.apache.cxf.ws.security.wss4j;
+import java.io.IOException;
import java.lang.reflect.Method;
import java.security.Provider;
import java.security.cert.Certificate;
@@ -28,7 +29,9 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
+import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
@@ -50,6 +53,7 @@ import org.apache.cxf.binding.soap.saaj.SAAJUtils;
import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.PropertyUtils;
+import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.helpers.DOMUtils;
@@ -67,6 +71,7 @@ import org.apache.wss4j.common.ConfigurationConstants;
import org.apache.wss4j.common.cache.ReplayCache;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.ThreadLocalSecurityProvider;
+import org.apache.wss4j.common.ext.WSPasswordCallback;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.dom.WSConstants;
import org.apache.wss4j.dom.WSDataRef;
@@ -652,6 +657,33 @@ public class WSS4JInInterceptor extends
AbstractWSS4JInterceptor {
}
}
+ // Defer to SecurityConstants.SIGNATURE_PASSWORD for decryption if no
callback handler is defined
+ if (cbHandler == null) {
+ String signatureUser =
+
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SIGNATURE_USERNAME,
+
(SoapMessage)reqData.getMsgContext());
+ String password =
+
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SIGNATURE_PASSWORD,
+
(SoapMessage)reqData.getMsgContext());
+ if (!(StringUtils.isEmpty(signatureUser) ||
StringUtils.isEmpty(password))) {
+ cbHandler = new CallbackHandler() {
+
+ @Override
+ public void handle(Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+ for (Callback c : callbacks) {
+ WSPasswordCallback pwCallback =
(WSPasswordCallback)c;
+ if (WSPasswordCallback.DECRYPT ==
pwCallback.getUsage()
+ &&
signatureUser.equals(pwCallback.getIdentifier())) {
+ pwCallback.setPassword(password);
+ }
+ }
+ }
+ };
+ }
+
+ }
+
Endpoint ep =
((SoapMessage)reqData.getMsgContext()).getExchange().getEndpoint();
if (ep != null && ep.getEndpointInfo() != null) {
TokenStore store =
TokenStoreUtils.getTokenStore((SoapMessage)reqData.getMsgContext());
diff --git
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
index 9ecc52a..945755a 100644
---
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
+++
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/AbstractBindingBuilder.java
@@ -590,7 +590,11 @@ public abstract class AbstractBindingBuilder extends
AbstractCommonBindingHandle
throw new Fault(e1);
}
- String password = getPassword(uname, token,
WSPasswordCallback.SIGNATURE);
+ String password =
+
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SIGNATURE_PASSWORD,
message);
+ if (StringUtils.isEmpty(password)) {
+ password = getPassword(uname, token, WSPasswordCallback.SIGNATURE);
+ }
sig.setUserInfo(uname, password);
try {
sig.prepare(secToken.getCrypto());
@@ -946,7 +950,11 @@ public abstract class AbstractBindingBuilder extends
AbstractCommonBindingHandle
}
String password = samlCallback.getIssuerKeyPassword();
if (password == null) {
- password = getPassword(issuerName, token,
WSPasswordCallback.SIGNATURE);
+ password =
+
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SIGNATURE_PASSWORD,
message);
+ if (StringUtils.isEmpty(password)) {
+ password = getPassword(issuerName, token,
WSPasswordCallback.SIGNATURE);
+ }
}
Crypto crypto = samlCallback.getIssuerCrypto();
if (crypto == null) {
@@ -1883,7 +1891,11 @@ public abstract class AbstractBindingBuilder extends
AbstractCommonBindingHandle
}
}
- String password = getPassword(user, token,
WSPasswordCallback.SIGNATURE);
+ String password =
+
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SIGNATURE_PASSWORD,
message);
+ if (StringUtils.isEmpty(password)) {
+ password = getPassword(user, token, WSPasswordCallback.SIGNATURE);
+ }
sig.setUserInfo(user, password);
sig.setSignatureAlgorithm(binding.getAlgorithmSuite().getAsymmetricSignature());
AlgorithmSuiteType algType =
binding.getAlgorithmSuite().getAlgorithmSuiteType();
diff --git
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
index b9d34c9..3a1b7c4 100644
---
a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
+++
b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/policyhandlers/TransportBindingHandler.java
@@ -32,6 +32,7 @@ import javax.xml.soap.SOAPMessage;
import org.w3c.dom.Element;
import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.rt.security.utils.SecurityUtils;
@@ -378,7 +379,7 @@ public class TransportBindingHandler extends
AbstractBindingBuilder {
dkSig.setStoreBytesInAttachment(storeBytesInAttachment);
dkSig.setExpandXopInclude(isExpandXopInclude());
dkSig.setWsDocInfo(wsDocInfo);
-
+
AlgorithmSuiteType algType =
binding.getAlgorithmSuite().getAlgorithmSuiteType();
dkSig.setDerivedKeyLength(algType.getSignatureDerivedKeyLength() /
8);
@@ -465,7 +466,7 @@ public class TransportBindingHandler extends
AbstractBindingBuilder {
dkSign.setStoreBytesInAttachment(storeBytesInAttachment);
dkSign.setExpandXopInclude(isExpandXopInclude());
dkSign.setWsDocInfo(wsDocInfo);
-
+
AlgorithmSuite algorithmSuite = tbinding.getAlgorithmSuite();
//Setting the AttachedReference or the UnattachedReference according
to the flag
@@ -585,7 +586,13 @@ public class TransportBindingHandler extends
AbstractBindingBuilder {
String userNameKey = SecurityConstants.SIGNATURE_USERNAME;
uname =
(String)SecurityUtils.getSecurityPropertyValue(userNameKey, message);
}
- String password = getPassword(uname, token,
WSPasswordCallback.SIGNATURE);
+
+ String password =
+
(String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SIGNATURE_PASSWORD,
message);
+ if (StringUtils.isEmpty(password)) {
+ password = getPassword(uname, token,
WSPasswordCallback.SIGNATURE);
+ }
+
sig.setUserInfo(uname, password);
sig.setSignatureAlgorithm(binding.getAlgorithmSuite().getAsymmetricSignature());
} else {
diff --git
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
index 5d59e8b..07db942 100644
---
a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
+++
b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/xml/JAXRSXmlSecTest.java
@@ -805,6 +805,49 @@ public class JAXRSXmlSecTest extends
AbstractBusClientServerTestBase {
}
}
+ @Test
+ public void testSignaturePassword() throws Exception {
+ String address = "https://localhost:" + test.port +
"/xmlsig/bookstore/books";
+
+ JAXRSClientFactoryBean bean = new JAXRSClientFactoryBean();
+ bean.setAddress(address);
+
+ SpringBusFactory bf = new SpringBusFactory();
+ URL busFile = JAXRSXmlSecTest.class.getResource("client.xml");
+ Bus springBus = bf.createBus(busFile.toString());
+ bean.setBus(springBus);
+
+ Map<String, Object> properties = new HashMap<>();
+ properties.put(SecurityConstants.SIGNATURE_USERNAME, "alice");
+ properties.put(SecurityConstants.SIGNATURE_PASSWORD, "password");
+ properties.put(SecurityConstants.SIGNATURE_PROPERTIES,
+
"org/apache/cxf/systest/jaxrs/security/alice.properties");
+ bean.setProperties(properties);
+ if (test.streaming) {
+ XmlSecOutInterceptor sigOutInterceptor = new
XmlSecOutInterceptor();
+ sigOutInterceptor.setSignRequest(true);
+ sigOutInterceptor.setKeyInfoMustBeAvailable(true);
+ bean.getOutInterceptors().add(sigOutInterceptor);
+
+ XmlSecInInterceptor sigInInterceptor = new XmlSecInInterceptor();
+ sigInInterceptor.setRequireSignature(true);
+ bean.setProvider(sigInInterceptor);
+ } else {
+ XmlSigOutInterceptor sigOutInterceptor = new
XmlSigOutInterceptor();
+ sigOutInterceptor.setKeyInfoMustBeAvailable(true);
+ bean.getOutInterceptors().add(sigOutInterceptor);
+
+ XmlSigInInterceptor sigInInterceptor = new XmlSigInInterceptor();
+ sigInInterceptor.setKeyInfoMustBeAvailable(true);
+ bean.getInInterceptors().add(sigInInterceptor);
+ }
+
+ WebClient wc = bean.createWebClient();
+
WebClient.getConfig(wc).getHttpConduit().getClient().setReceiveTimeout(10000000L);
+ Book book = wc.type("application/xml").post(new Book("CXF", 126L),
Book.class);
+ assertEquals(126L, book.getId());
+ }
+
private static final class TestParam {
final String port;
final boolean streaming;
diff --git
a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/password/PasswordPropertiesTest.java
b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/password/PasswordPropertiesTest.java
index 31ef815..fd68f33 100644
---
a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/password/PasswordPropertiesTest.java
+++
b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/password/PasswordPropertiesTest.java
@@ -148,4 +148,37 @@ public class PasswordPropertiesTest extends
AbstractBusClientServerTestBase {
bus.shutdown(true);
}
+ @org.junit.Test
+ public void testAsymmetricBinding() throws Exception {
+
+ SpringBusFactory bf = new SpringBusFactory();
+
+ Bus bus = bf.createBus();
+ BusFactory.setDefaultBus(bus);
+ BusFactory.setThreadDefaultBus(bus);
+
+ URL wsdl =
PasswordPropertiesTest.class.getResource("DoubleItPassword.wsdl");
+ Service service = Service.create(wsdl, SERVICE_QNAME);
+ QName portQName = new QName(NAMESPACE, "DoubleItAsymmetricPort");
+
+ DoubleItPortType port =
+ service.getPort(portQName, DoubleItPortType.class);
+ updateAddressPort(port, PORT);
+
+ if (test.isStreaming()) {
+ SecurityTestUtil.enableStreaming(port);
+ }
+
+ Client client = ClientProxy.getClient(port);
+ client.getRequestContext().put(SecurityConstants.SIGNATURE_USERNAME,
"alice");
+ client.getRequestContext().put(SecurityConstants.SIGNATURE_PROPERTIES,
"alice.properties");
+ client.getRequestContext().put(SecurityConstants.SIGNATURE_PASSWORD,
"password");
+ client.getRequestContext().put(SecurityConstants.ENCRYPT_USERNAME,
"bob");
+ client.getRequestContext().put(SecurityConstants.ENCRYPT_PROPERTIES,
"bob.properties");
+
+ assertEquals(50, port.doubleIt(25));
+
+ ((java.io.Closeable)port).close();
+ bus.shutdown(true);
+ }
}
diff --git
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/password/DoubleItPassword.wsdl
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/password/DoubleItPassword.wsdl
index 03b2bcb..3425ca8 100644
---
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/password/DoubleItPassword.wsdl
+++
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/password/DoubleItPassword.wsdl
@@ -51,6 +51,22 @@
</wsdl:fault>
</wsdl:operation>
</wsdl:binding>
+ <wsdl:binding name="DoubleItAsymmetricBinding" type="tns:DoubleItPortType">
+ <wsp:PolicyReference URI="#DoubleItAsymmetricPolicy"/>
+ <soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="DoubleIt">
+ <soap:operation soapAction=""/>
+ <wsdl:input>
+ <soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal"/>
+ </wsdl:output>
+ <wsdl:fault name="DoubleItFault">
+ <soap:body use="literal" name="DoubleItFault"/>
+ </wsdl:fault>
+ </wsdl:operation>
+ </wsdl:binding>
<wsdl:service name="DoubleItService">
<wsdl:port name="DoubleItUTPort" binding="tns:DoubleItUTBinding">
@@ -59,6 +75,9 @@
<wsdl:port name="DoubleItUTSignedPort"
binding="tns:DoubleItUTSignedBinding">
<soap:address location="http://localhost:9001/DoubleItUTSigned"/>
</wsdl:port>
+ <wsdl:port name="DoubleItAsymmetricPort"
binding="tns:DoubleItAsymmetricBinding">
+ <soap:address location="http://localhost:9001/DoubleItAsymmetric"/>
+ </wsdl:port>
</wsdl:service>
<wsp:Policy wsu:Id="DoubleItUTSupportingPolicy">
@@ -125,5 +144,51 @@
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
+ <wsp:Policy wsu:Id="DoubleItAsymmetricPolicy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:AsymmetricBinding>
+ <wsp:Policy>
+ <sp:InitiatorToken>
+ <wsp:Policy>
+ <sp:X509Token
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
+ <wsp:Policy>
+ <sp:WssX509V3Token10/>
+ </wsp:Policy>
+ </sp:X509Token>
+ </wsp:Policy>
+ </sp:InitiatorToken>
+ <sp:RecipientToken>
+ <wsp:Policy>
+ <sp:X509Token
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
+ <wsp:Policy>
+ <sp:WssX509V3Token10/>
+ </wsp:Policy>
+ </sp:X509Token>
+ </wsp:Policy>
+ </sp:RecipientToken>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Lax/>
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp/>
+ <sp:OnlySignEntireHeadersAndBody/>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic128/>
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ </wsp:Policy>
+ </sp:AsymmetricBinding>
+ <sp:EncryptedParts>
+ <sp:Body/>
+ </sp:EncryptedParts>
+ <sp:SignedParts>
+ <sp:Body/>
+ </sp:SignedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
</wsdl:definitions>
diff --git
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/password/server.xml
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/password/server.xml
index 86ec297..8d4268b 100644
---
a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/password/server.xml
+++
b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/password/server.xml
@@ -54,5 +54,18 @@
</jaxws:properties>
</jaxws:endpoint>
+ <jaxws:endpoint xmlns:s="http://www.example.org/contract/DoubleIt"
id="Asymmetric"
+
address="http://localhost:${testutil.ports.password.Server}/DoubleItAsymmetric"
serviceName="s:DoubleItService"
+ endpointName="s:DoubleItAsymmetricPort"
implementor="org.apache.cxf.systest.ws.common.DoubleItImpl"
+
wsdlLocation="org/apache/cxf/systest/ws/password/DoubleItPassword.wsdl">
+ <jaxws:properties>
+ <entry key="security.signature.username" value="bob"/>
+ <entry key="security.signature.password" value="password"/>
+ <entry key="security.signature.properties" value="bob.properties"/>
+ <entry key="security.encryption.properties"
value="alice.properties"/>
+ <entry key="security.encryption.username" value="alice"/>
+ </jaxws:properties>
+ </jaxws:endpoint>
+
</beans>
\ No newline at end of file