ws security - WCF consuming legacy webservices -


i having issue consuming legacy webservice using wcf. resolved 1 issue dealing fact webservice using different sign , encryption keys. when make webservice call version miss match response. when @ envelope produced in wse notice version of soap different 1 produced wcf.

my wse envelope header looks this:

<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

whereas wcf enveloped header

<s:envelope xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope"> 

i added code try , change namespace , prefix of soap envelope.

        endpointaddress serviceendpoint =              new endpointaddress(new uri("http://mylegacywebservice.com"));         custombinding binding = new custombinding();         asymmetricsecuritybindingelement securitybe =          securitybindingelement.createmutualcertificateduplexbindingelement(                 messagesecurityversion.wssecurity10wstrust13wssecureconversation13wssecuritypolicy12basicsecurityprofile10);         // add custom identityverifier because service uses 2 certificates          // (one signing , 1 encryption) , endpoint identity          // contains single identity claim.         securitybe.localclientsettings.identityverifier = new myidentityverifier();         binding.elements.add(securitybe);         compositeduplexbindingelement compositeduplex =          new compositeduplexbindingelement();         compositeduplex.clientbaseaddress = new uri("http://mylegacywebservice.com");         binding.elements.add(compositeduplex);          binding.elements.add(new onewaybindingelement());          binding.elements.add(new  httptransportbindingelement());           dictionary<string, string> namespacetoprefixmapping = new dictionary<string, string>  {      { "http://schemas.xmlsoap.org/soap/envelope/", "soap" },      { "http://schemas.xmlsoap.org/ws/2004/08/addressing", "wsa" },  };    binding = replaceprefixmessageencodingbindingelement.replaceencodingbindingelement(      new wshttpbinding(securitymode.none),      namespacetoprefixmapping);  

below prefixreplace.cs:

public class prefixreplacer    {      const string xmlnsnamespace = "http://www.w3.org/2000/xmlns/";      dictionary<string, string> namespacetonewprefixmapping = new dictionary<string, string>();    public void addnamespace(string namespaceuri, string newprefix)  {      this.namespacetonewprefixmapping.add(namespaceuri, newprefix);  }   public void changeprefixes(xmldocument doc)  {      xmlelement element = doc.documentelement;      xmlelement newelement = changeprefixes(doc, element);      doc.loadxml(newelement.outerxml);  }   private xmlelement changeprefixes(xmldocument doc, xmlelement element)  {      string newprefix;      if (this.namespacetonewprefixmapping.trygetvalue(element.namespaceuri, out newprefix))      {          xmlelement newelement = doc.createelement(newprefix, element.localname, element.namespaceuri);          list<xmlnode> children = new list<xmlnode>(element.childnodes.cast<xmlnode>());          list<xmlattribute> attributes = new list<xmlattribute>(element.attributes.cast<xmlattribute>());          foreach (xmlnode child in children)          {              newelement.appendchild(child);          }           foreach (xmlattribute attr in attributes)          {              newelement.attributes.append(attr);          }           element = newelement;      }       list<xmlattribute> newattributes = new list<xmlattribute>();      bool modified = false;      (int = 0; < element.attributes.count; i++)      {          xmlattribute attr = element.attributes[i];          if (this.namespacetonewprefixmapping.trygetvalue(attr.namespaceuri, out newprefix))          {              xmlattribute newattr = doc.createattribute(newprefix, attr.localname, attr.namespaceuri);              newattr.value = attr.value;              newattributes.add(newattr);              modified = true;          }          else if (attr.namespaceuri == xmlnsnamespace && this.namespacetonewprefixmapping.trygetvalue(attr.value, out newprefix))          {              xmlattribute newattr;              if (newprefix != "")              {                  newattr = doc.createattribute("xmlns", newprefix, xmlnsnamespace);              }              else              {                  newattr = doc.createattribute("xmlns");              }               newattr.value = attr.value;              newattributes.add(newattr);              modified = true;          }          else          {              newattributes.add(attr);          }      }       if (modified)      {          element.attributes.removeall();          foreach (var attr in newattributes)          {              element.attributes.append(attr);          }      }       list<keyvaluepair<xmlnode, xmlnode>> toreplace = new list<keyvaluepair<xmlnode, xmlnode>>();      foreach (xmlnode child in element.childnodes)      {          xmlelement childelement = child xmlelement;          if (childelement != null)          {              xmlelement newchildelement = changeprefixes(doc, childelement);              if (newchildelement != childelement)              {                  toreplace.add(new keyvaluepair<xmlnode, xmlnode>(childelement, newchildelement));              }          }      }       if (toreplace.count > 0)      {          (int = 0; < toreplace.count; i++)          {              element.insertafter(toreplace[i].value, toreplace[i].key);              element.removechild(toreplace[i].key);          }      }       return element;  }  

}

below replaceprefixmessageencodingbindingelement:

public class replaceprefixmessageencodingbindingelement : messageencodingbindingelement  {      messageencodingbindingelement inner;      dictionary<string, string> namespacetoprefixmapping = new dictionary<string, string>();  public replaceprefixmessageencodingbindingelement(messageencodingbindingelement inner)  {      this.inner = inner;  }   private replaceprefixmessageencodingbindingelement(replaceprefixmessageencodingbindingelement other)  {      this.inner = other.inner;      this.namespacetoprefixmapping = new dictionary<string, string>(other.namespacetoprefixmapping);  }   public void addnamespacemapping(string namespaceuri, string newprefix)  {      this.namespacetoprefixmapping.add(namespaceuri, newprefix);  }   public override messageencoderfactory createmessageencoderfactory()  {      return new replaceprefixmessageencoderfactory(this.inner.createmessageencoderfactory(), this.namespacetoprefixmapping);  }   public override messageversion messageversion  {      { return this.inner.messageversion; }      set { this.inner.messageversion = value; }  }   public override bindingelement clone()  {      return new replaceprefixmessageencodingbindingelement(this);  }   public override ichannellistener<tchannel> buildchannellistener<tchannel>(bindingcontext context)  {      context.bindingparameters.add(this);      return context.buildinnerchannellistener<tchannel>();  }   public override bool canbuildchannellistener<tchannel>(bindingcontext context)  {      return context.canbuildinnerchannellistener<tchannel>();  }   public static custombinding replaceencodingbindingelement(binding originalbinding, dictionary<string, string> namespacetoprefixmapping)  {      custombinding custom = originalbinding custombinding;      if (custom == null)      {          custom = new custombinding(originalbinding);      }       (int = 0; < custom.elements.count; i++)      {          if (custom.elements[i] messageencodingbindingelement)          {              replaceprefixmessageencodingbindingelement element = new replaceprefixmessageencodingbindingelement((messageencodingbindingelement)custom.elements[i]);              foreach (var mapping in namespacetoprefixmapping)              {                  element.addnamespacemapping(mapping.key, mapping.value);              }               custom.elements[i] = element;              break;          }      }       return custom;  }  


Comments