Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
OpenCMIS 1.0.0
-
None
-
chemistry-opencmis-server-bindings-1.0.0.jar
cxf-rt-bindings-soap-3.0.10.jar
Description
Problem and Steps to reproduce: When a user does a SOAP call with mustUnderstand="1" flag in the security header:
<?xml version="1.0" encoding="UTF-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <s:Header> <o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" s:mustUnderstand="1" > <o:UsernameToken u:Id="uuid-19e89b95-2c59-4b20-9a59-f2940d1a1217-3"> <o:Username>admin</o:Username> <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">admin</o:Password> </o:UsernameToken> </o:Security> </s:Header> <s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <getRepositories xmlns="http://docs.oasis-open.org/ns/cmis/messaging/200908/"> <extension xsi:nil="true" /> </getRepositories> </s:Body> </s:Envelope>
We are getting this error:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <soap:Fault> <faultcode>soap:MustUnderstand</faultcode> <faultstring>MustUnderstand headers: [{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood.</faultstring> </soap:Fault> </soap:Body> </soap:Envelope>
Proposed solution: In my opinion org.apache.chemistry.opencmis.server.impl.webservices.UsernameTokenInterceptor should have implemented the getUnderstoodHeaders method to let the org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor know that the security header is understood.
private void initServiceSideInfo(Set<QName> mustUnderstandQNames, SoapMessage soapMessage, Set<URI> serviceRoles, Set<QName> paramHeaders) { if (paramHeaders != null) { mustUnderstandQNames.addAll(paramHeaders); } for (Interceptor<? extends org.apache.cxf.message.Message> interceptorInstance : soapMessage.getInterceptorChain()) { if (interceptorInstance instanceof SoapInterceptor) { SoapInterceptor si = (SoapInterceptor) interceptorInstance; Set<URI> roles = si.getRoles(); if (roles != null) { serviceRoles.addAll(roles); } Set<QName> understoodHeaders = si.getUnderstoodHeaders(); // <--- Here is where all the interceptors, including the UsernameTokenInterceptor is queried for known headers if (understoodHeaders != null) { mustUnderstandQNames.addAll(understoodHeaders); } } } } private void checkUltimateReceiverHeaders(Set<Header> ultimateReceiverHeaders, Set<QName> mustUnderstandQNames, SoapMessage soapMessage) { soapMessage.getInterceptorChain() .add(new UltimateReceiverMustUnderstandInterceptor(mustUnderstandQNames)); ....... if (!ultimateReceiverHeaders.isEmpty()) { Set<QName> notFound = new HashSet<QName>(); for (Header h : ultimateReceiverHeaders) { if (!mustUnderstandQNames.contains(h.getName())) { //<-------- this is where the problem happens, because the UsernameTokenInterceptor did not inform it knows about the security headers notFound.add(h.getName()); } } if (!notFound.isEmpty()) { // Defer throwing soap fault exception in SOAPHeaderInterceptor once the isOneway can // be detected soapMessage.put(MustUnderstandInterceptor.UNKNOWNS, notFound); soapMessage.getInterceptorChain().add(ending); } } }
I think the same idea is used by other people as a workaround : http://mail-archives.apache.org/mod_mbox/cxf-users/200911.mbox/%3C4B0BF10B.4070604@yahoo.gr%3E
Let me know if you need extra details (or if we are not using it correctly).
Note that: we recently updated from 0.11, and that worked fine for us (for this use case) - but that was completely ignoring the mustUnderstand="1" from what we saw.
We only bring the minimal required dependencies for the open-cmis.
Here are some other libraries in our project that may interest you:
cxf-core-3.0.10.jar
wss4j-1.6.19.jar
wsdl4j-1.6.3.jar