You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2025/07/02 12:41:37 UTC
(cxf) 02/05: Fixing most WS-Security tests
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch coheigea/wss4j-saml-refactor
in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 851e5c6b5cdacc69df0b4c428500b0850d34c03f
Author: Colm O hEigeartaigh <co...@apache.org>
AuthorDate: Tue Jul 1 10:24:10 2025 +0100
Fixing most WS-Security tests
---
.../security/wss4j/AbstractWSS4JInterceptor.java | 25 ++++++--
.../cxf/ws/security/wss4j/WSS4JInInterceptor.java | 10 +++-
.../cxf/ws/security/wss4j/WSS4JOutInterceptor.java | 70 +++++++++++++++++++++-
.../cxf/ws/security/wss4j/WSS4JInOutTest.java | 2 +-
.../ws/security/wss4j/WSS4JOutInterceptorTest.java | 1 -
.../apache/cxf/systest/ws/action/ActionTest.java | 2 +-
.../ws/fault/AbstractModifyRequestInterceptor.java | 2 +-
.../cxf/systest/ws/saml/CustomSaml2Validator.java | 8 +--
.../ws/saml/client/SamlCallbackHandler.java | 2 +-
.../cxf/systest/ws/tokens/DoubleItBSTImpl.java | 2 +-
.../cxf/systest/ws/ut/CustomUTValidator.java | 6 +-
.../ws/ut/SecurityHeaderCacheInterceptor.java | 2 +-
12 files changed, 107 insertions(+), 25 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 a77b1c554f..b667288810 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
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;
import org.apache.cxf.binding.soap.SoapMessage;
@@ -94,10 +95,6 @@ public abstract class AbstractWSS4JInterceptor extends WSHandler implements Soap
properties.put(key, value);
}
- public String getPassword(Object msgContext) {
- return (String)((Message)msgContext).getContextualProperty("password");
- }
-
public Object getProperty(Object msgContext, String key) {
if (msgContext == null) {
return null;
@@ -110,8 +107,24 @@ public abstract class AbstractWSS4JInterceptor extends WSHandler implements Soap
return obj;
}
- public void setPassword(Object msgContext, String password) {
- ((Message)msgContext).put("password", password);
+ @Override
+ public CallbackHandler getCallbackHandler(
+ String callbackHandlerClass,
+ String callbackHandlerRef,
+ RequestData requestData
+ ) throws WSSecurityException {
+ if (callbackHandlerRef != null && properties.containsKey(callbackHandlerRef)) {
+ return (CallbackHandler)properties.get(callbackHandlerRef);
+ }
+ return super.getCallbackHandler(callbackHandlerClass, callbackHandlerRef, requestData);
+ }
+
+ @Override
+ protected String getString(String key, Map<String, Object> mc) {
+ if (properties.containsKey(key)) {
+ return (String)properties.get(key);
+ }
+ return super.getString(key, mc);
}
public void setProperty(Object msgContext, String key, Object value) {
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 e797817922..8c738be7f5 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
@@ -185,6 +185,11 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor {
public Object getProperty(Object msgContext, String key) {
// use the superclass first
Object result = super.getProperty(msgContext, key);
+ if (result == null) {
+ result = msgContext instanceof SoapMessage
+ ? ((SoapMessage)msgContext).getContextualProperty(key)
+ : null;
+ }
// handle the special case of the SEND_SIGV
if (result == null
@@ -223,6 +228,7 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor {
boolean utWithCallbacks =
MessageUtils.getContextualBoolean(msg, SecurityConstants.VALIDATE_TOKEN, true);
translateProperties(msg);
+
RequestData reqData = new CXFRequestData();
@@ -297,8 +303,8 @@ public class WSS4JInInterceptor extends AbstractWSS4JInterceptor {
// Only search for and expand (Signed) XOP Elements if MTOM is enabled (and not
// explicitly specified by the user)
- if (getString(ConfigurationConstants.EXPAND_XOP_INCLUDE_FOR_SIGNATURE, msg) == null
- && getString(ConfigurationConstants.EXPAND_XOP_INCLUDE, msg) == null) {
+ if (getProperty(msg, ConfigurationConstants.EXPAND_XOP_INCLUDE_FOR_SIGNATURE) == null
+ && getProperty(msg, ConfigurationConstants.EXPAND_XOP_INCLUDE) == null) {
reqData.setExpandXopInclude(AttachmentUtil.isMtomEnabled(msg));
}
diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java
index 1290a4eb28..a4e0ade215 100644
--- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java
+++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java
@@ -18,6 +18,7 @@
*/
package org.apache.cxf.ws.security.wss4j;
+import java.io.IOException;
import java.security.Provider;
import java.util.Collection;
import java.util.Collections;
@@ -28,6 +29,10 @@ import java.util.Set;
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 org.w3c.dom.Document;
import jakarta.xml.soap.SOAPMessage;
@@ -38,12 +43,16 @@ import org.apache.cxf.binding.soap.SoapVersion;
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.common.util.StringUtils;
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.cxf.rt.security.utils.SecurityUtils;
+import org.apache.cxf.ws.security.SecurityConstants;
import org.apache.wss4j.common.ConfigurationConstants;
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.common.dom.WSConstants;
import org.apache.wss4j.common.dom.action.Action;
@@ -86,6 +95,11 @@ public class WSS4JOutInterceptor extends AbstractWSS4JInterceptor {
public Object getProperty(Object msgContext, String key) {
// use the superclass first
Object result = super.getProperty(msgContext, key);
+ if (result == null) {
+ result = msgContext instanceof SoapMessage
+ ? ((SoapMessage)msgContext).getContextualProperty(key)
+ : null;
+ }
// handle the special case of the RECV_RESULTS
if (result == null
@@ -181,7 +195,7 @@ public class WSS4JOutInterceptor extends AbstractWSS4JInterceptor {
CastUtils.cast((List<?>)getProperty(mc, WSHandlerConstants.HANDLER_ACTIONS));
if (actions == null) {
// If null then just fall back to the "action" String
- String action = getString(ConfigurationConstants.ACTION, mc);
+ String action = (String)getProperty(mc, ConfigurationConstants.ACTION);
if (action == null) {
throw new SoapFault(new Message("NO_ACTION", LOG), version
.getReceiver());
@@ -195,13 +209,14 @@ public class WSS4JOutInterceptor extends AbstractWSS4JInterceptor {
translateProperties(mc);
reqData.setMsgContext(mc);
+ reqData.setCallbackHandler(getCallback(reqData));
reqData.setAttachmentCallbackHandler(new AttachmentCallbackHandler(mc));
// Enable XOP Include unless the user has explicitly configured it
- if (getString(ConfigurationConstants.EXPAND_XOP_INCLUDE, mc) == null) {
+ if (getProperty(mc, ConfigurationConstants.EXPAND_XOP_INCLUDE) == null) {
reqData.setExpandXopInclude(AttachmentUtil.isMtomEnabled(mc));
}
- if (getString(ConfigurationConstants.STORE_BYTES_IN_ATTACHMENT, mc) == null) {
+ if (getProperty(mc, ConfigurationConstants.STORE_BYTES_IN_ATTACHMENT) == null) {
reqData.setStoreBytesInAttachment(AttachmentUtil.isMtomEnabled(mc));
}
@@ -346,4 +361,53 @@ public class WSS4JOutInterceptor extends AbstractWSS4JInterceptor {
return null;
}
}
+
+ private CallbackHandler getCallback(RequestData reqData) throws WSSecurityException {
+ Object o =
+ SecurityUtils.getSecurityPropertyValue(SecurityConstants.CALLBACK_HANDLER,
+ (SoapMessage)reqData.getMsgContext());
+ CallbackHandler cbHandler;
+ try {
+ cbHandler = SecurityUtils.getCallbackHandler(o);
+ } catch (Exception ex) {
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, ex);
+ }
+
+ if (cbHandler == null) {
+ try {
+ cbHandler = getPasswordCallbackHandler(reqData);
+ } catch (WSSecurityException sec) {
+ // Ignore
+ }
+ }
+
+ // Defer to SecurityConstants.PASSWORD or "password" if no callback handler is defined
+ if (cbHandler == null) {
+ String password =
+ (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.PASSWORD,
+ (SoapMessage)reqData.getMsgContext());
+ if (StringUtils.isEmpty(password)) {
+ password = (String)SecurityUtils.getSecurityPropertyValue("password",
+ (SoapMessage)reqData.getMsgContext());
+ }
+
+ if (!StringUtils.isEmpty(password)) {
+ final String contextualPassword = password;
+ cbHandler = new CallbackHandler() {
+
+ @Override
+ public void handle(Callback[] callbacks)
+ throws IOException, UnsupportedCallbackException {
+ for (Callback c : callbacks) {
+ WSPasswordCallback pwCallback = (WSPasswordCallback)c;
+ pwCallback.setPassword(contextualPassword);
+ }
+ }
+ };
+ }
+
+ }
+
+ return cbHandler;
+ }
}
diff --git a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JInOutTest.java b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JInOutTest.java
index 87ffa14b2e..35232ae529 100644
--- a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JInOutTest.java
+++ b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JInOutTest.java
@@ -53,7 +53,7 @@ import org.apache.wss4j.common.principal.UsernameTokenPrincipal;
import org.apache.wss4j.common.dom.WSConstants;
import org.apache.wss4j.common.WSDataRef;
import org.apache.wss4j.common.dom.engine.WSSecurityEngineResult;
-import org.apache.wss4j.dom.handler.WSHandlerConstants;
+import org.apache.wss4j.dom.handler.WSHandlerConstants;
import org.apache.wss4j.dom.handler.WSHandlerResult;
import org.apache.xml.security.utils.Constants;
import org.apache.xml.security.utils.EncryptionConstants;
diff --git a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptorTest.java b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptorTest.java
index 55f1e85ba8..f02cf3e734 100644
--- a/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptorTest.java
+++ b/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptorTest.java
@@ -34,7 +34,6 @@ import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.dom.WSConstants;
import org.apache.wss4j.dom.action.UsernameTokenAction;
import org.apache.wss4j.common.dom.RequestData;
-import org.apache.wss4j.dom.handler.WSHandler;
import org.junit.Test;
diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/action/ActionTest.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/action/ActionTest.java
index 655bda7da5..993a154179 100644
--- a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/action/ActionTest.java
+++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/action/ActionTest.java
@@ -54,7 +54,7 @@ import org.apache.wss4j.common.SignatureActionToken;
import org.apache.wss4j.common.crypto.Crypto;
import org.apache.wss4j.common.crypto.CryptoFactory;
import org.apache.wss4j.common.ext.WSSecurityException;
-import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.common.dom.WSConstants;
import org.apache.wss4j.dom.handler.HandlerAction;
import org.apache.wss4j.dom.handler.WSHandlerConstants;
import org.apache.wss4j.stax.ext.WSSConstants;
diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/fault/AbstractModifyRequestInterceptor.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/fault/AbstractModifyRequestInterceptor.java
index 12a44099ef..3e62490506 100644
--- a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/fault/AbstractModifyRequestInterceptor.java
+++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/fault/AbstractModifyRequestInterceptor.java
@@ -39,7 +39,7 @@ import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.phase.PhaseInterceptor;
import org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor;
-import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.common.dom.WSConstants;
public abstract class AbstractModifyRequestInterceptor implements PhaseInterceptor<SoapMessage> {
diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/CustomSaml2Validator.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/CustomSaml2Validator.java
index 6d6535608f..38f0fa976e 100644
--- a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/CustomSaml2Validator.java
+++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/CustomSaml2Validator.java
@@ -22,9 +22,9 @@ import java.util.List;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.saml.SamlAssertionWrapper;
-import org.apache.wss4j.dom.handler.RequestData;
-import org.apache.wss4j.dom.validate.Credential;
-import org.apache.wss4j.dom.validate.SamlAssertionValidator;
+import org.apache.wss4j.common.dom.RequestData;
+import org.apache.wss4j.common.dom.validate.Credential;
+import org.apache.wss4j.common.saml.validate.SamlAssertionValidator;
import org.opensaml.saml.saml2.core.Assertion;
import org.opensaml.saml.saml2.core.AttributeStatement;
@@ -37,7 +37,7 @@ public class CustomSaml2Validator extends SamlAssertionValidator {
@Override
public Credential validate(Credential credential, RequestData data) throws WSSecurityException {
Credential validatedCredential = super.validate(credential, data);
- SamlAssertionWrapper assertion = validatedCredential.getSamlAssertion();
+ SamlAssertionWrapper assertion = (SamlAssertionWrapper)validatedCredential.getSamlAssertion();
if (!"sts".equals(assertion.getIssuerString())) {
throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/client/SamlCallbackHandler.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/client/SamlCallbackHandler.java
index e532da163b..b3296f5bff 100644
--- a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/client/SamlCallbackHandler.java
+++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/saml/client/SamlCallbackHandler.java
@@ -41,7 +41,7 @@ import org.apache.wss4j.common.saml.bean.SubjectBean;
import org.apache.wss4j.common.saml.bean.Version;
import org.apache.wss4j.common.saml.builder.SAML1Constants;
import org.apache.wss4j.common.saml.builder.SAML2Constants;
-import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.common.dom.WSConstants;
/**
* A CallbackHandler instance that is used by the STS to mock up a SAML Attribute Assertion.
diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/tokens/DoubleItBSTImpl.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/tokens/DoubleItBSTImpl.java
index 1fed98f3d3..86ba2ad003 100644
--- a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/tokens/DoubleItBSTImpl.java
+++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/tokens/DoubleItBSTImpl.java
@@ -26,7 +26,7 @@ import jakarta.xml.ws.WebServiceContext;
import org.apache.cxf.feature.Features;
import org.apache.cxf.helpers.CastUtils;
import org.apache.wss4j.common.token.BinarySecurity;
-import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
+import org.apache.wss4j.common.dom.engine.WSSecurityEngineResult;
import org.apache.wss4j.dom.handler.WSHandlerConstants;
import org.apache.wss4j.dom.handler.WSHandlerResult;
import org.example.contract.doubleit.DoubleItFault;
diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ut/CustomUTValidator.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ut/CustomUTValidator.java
index 4ff5fedc1d..a71b3aeebd 100644
--- a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ut/CustomUTValidator.java
+++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ut/CustomUTValidator.java
@@ -24,9 +24,9 @@ import javax.security.auth.Subject;
import org.apache.cxf.common.security.SimpleGroup;
import org.apache.wss4j.common.ext.WSSecurityException;
import org.apache.wss4j.common.principal.WSUsernameTokenPrincipalImpl;
-import org.apache.wss4j.dom.handler.RequestData;
-import org.apache.wss4j.dom.message.token.UsernameToken;
-import org.apache.wss4j.dom.validate.Credential;
+import org.apache.wss4j.common.dom.RequestData;
+import org.apache.wss4j.common.dom.message.token.UsernameToken;
+import org.apache.wss4j.common.dom.validate.Credential;
import org.apache.wss4j.dom.validate.UsernameTokenValidator;
/**
diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ut/SecurityHeaderCacheInterceptor.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ut/SecurityHeaderCacheInterceptor.java
index d0c5c688cc..80edf8333a 100644
--- a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ut/SecurityHeaderCacheInterceptor.java
+++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ut/SecurityHeaderCacheInterceptor.java
@@ -38,7 +38,7 @@ import org.apache.cxf.message.Message;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.phase.PhaseInterceptor;
import org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor;
-import org.apache.wss4j.dom.WSConstants;
+import org.apache.wss4j.common.dom.WSConstants;
/**
* Cache the first security header and then use it instead of all subsequent security headers, until