Uploaded image for project: 'Chemistry (Retired)'
  1. Chemistry (Retired)
  2. CMIS-1047

UsernameTokenInterceptor does not implement getUnderstoodHeaders

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • OpenCMIS 1.0.0
    • OpenCMIS 1.2.0
    • opencmis-server
    • 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.

      MustUnderstandInterceptor
        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

      Attachments

        Activity

          People

            fmui Florian Müller
            andrei.rebegea Andrei Rebegea
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: