diff --git a/security/src/main/java/org/springframework/ws/soap/security/AbstractWsSecurityInterceptor.java b/security/src/main/java/org/springframework/ws/soap/security/AbstractWsSecurityInterceptor.java
index bb5d4ac1..a6b6a917 100644
--- a/security/src/main/java/org/springframework/ws/soap/security/AbstractWsSecurityInterceptor.java
+++ b/security/src/main/java/org/springframework/ws/soap/security/AbstractWsSecurityInterceptor.java
@@ -24,9 +24,11 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.SoapBody;
+import org.springframework.ws.soap.SoapFault;
import org.springframework.ws.soap.SoapHeaderElement;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.server.SoapEndpointInterceptor;
+import org.springframework.ws.soap.soap11.Soap11Body;
/**
* Interceptor base class for interceptors that handle WS-Security.
@@ -42,19 +44,25 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
private static final QName WS_SECURITY_NAME =
new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security");
- /** Logger available to subclasses. */
+ /**
+ * Logger available to subclasses.
+ */
protected final Log logger = LogFactory.getLog(getClass());
private boolean secureResponse = true;
private boolean validateRequest = true;
- /** Indicates whether outgoing responsed are to be secured. Defaults to true. */
+ /**
+ * Indicates whether outgoing responsed are to be secured. Defaults to true.
+ */
public void setSecureResponse(boolean secureResponse) {
this.secureResponse = secureResponse;
}
- /** Indicates whether incoming request are to be validated. Defaults to true. */
+ /**
+ * Indicates whether incoming request are to be validated. Defaults to true.
+ */
public void setValidateRequest(boolean validateRequest) {
this.validateRequest = validateRequest;
}
@@ -70,6 +78,9 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
catch (WsSecurityValidationException ex) {
return handleValidationException(ex, messageContext);
}
+ catch (WsSecurityFaultException ex) {
+ return handleFaultException(ex, messageContext);
+ }
}
else {
return true;
@@ -87,13 +98,18 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
catch (WsSecuritySecurementException ex) {
return handleSecurementException(ex, messageContext);
}
+ catch (WsSecurityFaultException ex) {
+ return handleFaultException(ex, messageContext);
+ }
}
else {
return true;
}
}
- /** Returns true, i.e. faults are not secured. */
+ /**
+ * Returns true, i.e. faults are not secured.
+ */
public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
return true;
}
@@ -134,6 +150,30 @@ public abstract class AbstractWsSecurityInterceptor implements SoapEndpointInter
return false;
}
+ /**
+ * Handles a fault exception.Default implementation logs the given exception, and creates a SOAP Fault with the
+ * properties of the given exception, and returns false.
+ *
+ * @param ex the validation exception
+ * @param messageContext the message context
+ * @return true to continue processing the message, false (the default) otherwise
+ */
+ protected boolean handleFaultException(WsSecurityFaultException ex, MessageContext messageContext) {
+ if (logger.isWarnEnabled()) {
+ logger.warn("Could not handle request: " + ex.getMessage());
+ }
+ SoapBody response = ((SoapMessage) messageContext.getResponse()).getSoapBody();
+ SoapFault fault;
+ if (response instanceof Soap11Body) {
+ fault = ((Soap11Body) response).addFault(ex.getFaultCode(), ex.getFaultString(), Locale.ENGLISH);
+ }
+ else {
+ fault = response.addClientOrSenderFault(ex.getFaultString(), Locale.ENGLISH);
+ }
+ fault.setFaultActorOrRole(ex.getFaultActor());
+ return false;
+ }
+
/**
* Abstract template method. Subclasses are required to validate the request contained in the given {@link
* SoapMessage}, and replace the original request with the validated version.
diff --git a/security/src/main/java/org/springframework/ws/soap/security/WsSecurityFaultException.java b/security/src/main/java/org/springframework/ws/soap/security/WsSecurityFaultException.java
new file mode 100644
index 00000000..8faeccdc
--- /dev/null
+++ b/security/src/main/java/org/springframework/ws/soap/security/WsSecurityFaultException.java
@@ -0,0 +1,49 @@
+package org.springframework.ws.soap.security;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Exception indicating that a WS-Security executions should result in a SOAP Fault.
+ *
+ * @author Arjen Poutsma
+ * @since 1.0.1
+ */
+public abstract class WsSecurityFaultException extends WsSecurityException {
+
+ private QName faultCode;
+
+ private String faultString;
+
+ private String faultActor;
+
+ /**
+ * Construct a new WsSecurityFaultException with the given fault code, string, and actor.
+ */
+ public WsSecurityFaultException(QName faultCode, String faultString, String faultActor) {
+ super(faultString);
+ this.faultCode = faultCode;
+ this.faultString = faultString;
+ this.faultActor = faultActor;
+ }
+
+ /**
+ * Returns the fault code for the exception.
+ */
+ public QName getFaultCode() {
+ return faultCode;
+ }
+
+ /**
+ * Returns the fault string for the exception.
+ */
+ public String getFaultString() {
+ return faultString;
+ }
+
+ /**
+ * Returns the fault actor for the exception.
+ */
+ public String getFaultActor() {
+ return faultActor;
+ }
+}
diff --git a/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityFaultException.java b/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityFaultException.java
new file mode 100644
index 00000000..5556cb1c
--- /dev/null
+++ b/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityFaultException.java
@@ -0,0 +1,18 @@
+package org.springframework.ws.soap.security.xwss;
+
+import javax.xml.namespace.QName;
+
+import org.springframework.ws.soap.security.WsSecurityFaultException;
+
+/**
+ * XWSS-specific version of the {@link WsSecurityFaultException}.
+ *
+ * @author Arjen Poutsma
+ * @since 1.0.1
+ */
+public class XwsSecurityFaultException extends WsSecurityFaultException {
+
+ public XwsSecurityFaultException(QName faultCode, String faultString, String faultActor) {
+ super(faultCode, faultString, faultActor);
+ }
+}
diff --git a/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityInterceptor.java b/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityInterceptor.java
index 421ae3bb..dcfd27d4 100644
--- a/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityInterceptor.java
+++ b/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityInterceptor.java
@@ -24,6 +24,7 @@ import com.sun.xml.wss.ProcessingContext;
import com.sun.xml.wss.XWSSProcessor;
import com.sun.xml.wss.XWSSProcessorFactory;
import com.sun.xml.wss.XWSSecurityException;
+import com.sun.xml.wss.impl.WssSoapFaultException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
@@ -86,7 +87,9 @@ public class XwsSecurityInterceptor extends AbstractWsSecurityInterceptor implem
this.callbackHandler = new CallbackHandlerChain(callbackHandler);
}
- /** Sets the policy configuration to use for XWSS. Required. */
+ /**
+ * Sets the policy configuration to use for XWSS. Required.
+ */
public void setPolicyConfiguration(Resource policyConfiguration) {
this.policyConfiguration = policyConfiguration;
}
@@ -130,6 +133,9 @@ public class XwsSecurityInterceptor extends AbstractWsSecurityInterceptor implem
catch (XWSSecurityException ex) {
throw new XwsSecuritySecurementException(ex.getMessage(), ex);
}
+ catch (WssSoapFaultException ex) {
+ throw new XwsSecurityFaultException(ex.getFaultCode(), ex.getFaultString(), ex.getFaultActor());
+ }
}
/**
@@ -151,5 +157,9 @@ public class XwsSecurityInterceptor extends AbstractWsSecurityInterceptor implem
catch (XWSSecurityException ex) {
throw new XwsSecurityValidationException(ex.getMessage(), ex);
}
+ catch (WssSoapFaultException ex) {
+ throw new XwsSecurityFaultException(ex.getFaultCode(), ex.getFaultString(), ex.getFaultActor());
+ }
}
+
}
diff --git a/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecuritySecurementException.java b/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecuritySecurementException.java
index 3813c8e8..44eb3799 100644
--- a/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecuritySecurementException.java
+++ b/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecuritySecurementException.java
@@ -18,6 +18,12 @@ package org.springframework.ws.soap.security.xwss;
import org.springframework.ws.soap.security.WsSecuritySecurementException;
+/**
+ * XWSS-specific version of the {@link WsSecuritySecurementException}.
+ *
+ * @author Arjen Poutsma
+ * @since 1.0.0
+ */
public class XwsSecuritySecurementException extends WsSecuritySecurementException {
public XwsSecuritySecurementException(String msg) {
diff --git a/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityValidationException.java b/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityValidationException.java
index 409b5946..7c8af13e 100644
--- a/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityValidationException.java
+++ b/security/src/main/java/org/springframework/ws/soap/security/xwss/XwsSecurityValidationException.java
@@ -18,6 +18,12 @@ package org.springframework.ws.soap.security.xwss;
import org.springframework.ws.soap.security.WsSecurityValidationException;
+/**
+ * XWSS-specific version of the {@link WsSecurityValidationException}.
+ *
+ * @author Arjen Poutsma
+ * @since 1.0.0
+ */
public class XwsSecurityValidationException extends WsSecurityValidationException {
public XwsSecurityValidationException(String msg) {