Firtly, thank you for your reply.
Your e-mail pointed me to the relevant code (ReadHeadersInterceptor
specifically). I ended up reading CXF code and found that the headers
check is performed by the SOAP binding module and specifically the
MustUnderstandInterceptor.
To make the long story short, I have a more elegant solution with this
simple interceptor below.
The SOAP binding module of CXF checks the interceptor chain and calls
"getUnderstoodHeaders()" to see what the endpoint "understands". Then it
checks the headers present in the message against the headers understood
by the interceptors of the endpoint and complains if it finds a header
with "mustUnderstand" enabled has no interceptor that "understands" it.
Adding the "do-nothing" interceptor below will cause the check to pass
and prevent the exception. I prefer this because it's non-invasive (no
modification whatsoever occurs in the message).
import org.apache.ws.security.WSConstants;
public class WSSPassThroughInterceptor extends AbstractSoapInterceptor {
private static final Set<QName> HEADERS = new HashSet<QName>();
static {
HEADERS.add(new QName(WSConstants.WSSE_NS, WSConstants.WSSE_LN));
HEADERS.add(new QName(WSConstants.WSSE11_NS, WSConstants.WSSE_LN));
HEADERS.add(new QName(WSConstants.ENC_NS, WSConstants.ENC_DATA_LN));
}
public WSSPassThroughInterceptor() {
super(Phase.PRE_PROTOCOL);
}
public WSSPassThroughInterceptor(String phase) {
super(phase);
}
@Override
public Set<QName> getUnderstoodHeaders() {
return HEADERS;
}
public void handleMessage(SoapMessage soapMessage) {
// do nothing
// this interceptor simply returns all WS-Security headers in
its getUnderstoodHeaders()
// method, so that CXF does not complain that they have not been
"processed"
// this is useful if you only need to look at the non-encrypted XML
}
}
vickatvuuch wrote:
You can step on normal processing by making a following hack:
1. Make a custom interceptor either extending AbstractSoapInterceptor or
AbstractPhaseInterceptor<SoapMessage>
2. Install it right after CXF default ReadHeadersInterceptor
for example:
public IgnoreMustUnderstandHeadersInterceptor(Bus b) {
super(Phase.READ);
bus = b;
addAfter(ReadHeadersInterceptor.class);
}
3. Override public void handleMessage(SoapMessage message) {
4. Find all Header objects inside the message and update
setMustUnderstand(false);
message.getHeaders()
ReadHeadersInterceptor
message.getHeaders().add(shead);
karypid wrote:
Hi,
I have a CXF endpoint that uses @WebServiceProvider to process the SOAP
XML.
The sender uses WS-Security so the message includes in its SOAP header:
<wsse:Security
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
soap:mustUnderstand="1">
This causes CXF to throw an Exception saying:
23 Νοε 2009 10:30:22 πμ org.apache.cxf.phase.PhaseInterceptorChain
doIntercept
WARNING: Interceptor has thrown exception, unwinding now
org.apache.cxf.binding.soap.SoapFault: MustUnderstand headers:
[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security]
are not understood.
at
org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor$UltimateReceiverMustUnderstandInterceptor.handleMessage(MustUnderstandInterceptor.java:221)
... stack trace continues...
Now, I don't care about the encrypted portion of the message. I just
want to use the XML API-s to process the message in my:
@WebServiceProvider(...)
@ServiceMode(Mode.MESSAGE)
@BindingType(value = HTTPBinding.HTTP_BINDING)
public class AsyncMessagingServiceProvider implements Provider<Source> {
public Source invoke(Source request) {
// I need to look at the XML here, no need to decrypt / verify the
secured elements
}
So how can I tell CXF to just perform the invocation and not worry about
"understanding" that header? What are my options? I am thinking that it
is possible for an interceptor to mark a header as "understood" so that
CXF will not complain. Is there indeed an API for that?