Tutorial :Clueless about how to create SOAP header



Question:

I'm have near to none experience with SOAP protocol. The service I need to connect to required header. I think this is somewhat standard in Java but in C# one must create this header by hand.

Does anyone here been able to connect to similar service: have created the header or maybe even know about some standard library which would simplify creation of header? Can you share some code or references?

I also found a clue that maybe header will be generated if using WS2005, because there is WS3 addin for it. Can anybody comment this? After quick look at this addin I found simmilar fields as in Security header, but still wasn't able to create the header.


Solution:1

We were able to solve it with the following code:

public class SecurityHeader : System.ServiceModel.Channels.MessageHeader {      public string userName;      public string password;        protected override void OnWriteStartHeader (System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion messageVersion)      {          writer.WriteStartElement("wsse", Name, Namespace);          writer.WriteXmlnsAttribute("wsse", Namespace);      }        protected override void OnWriteHeaderContents (System.Xml.XmlDictionaryWriter writer, System.ServiceModel.Channels.MessageVersion messageVersion)      {          writer.WriteStartElement("wsse", "UsernameToken", Namespace);            writer.WriteStartElement("wsse", "Username", Namespace);          writer.WriteValue(userName);          writer.WriteEndElement();            writer.WriteStartElement("wsse", "Password", Namespace);          writer.WriteValue(password);          writer.WriteEndElement();            writer.WriteEndElement();        }        public override string Name      {          get { return "Security"; }      }        public override string Namespace      {          get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }      }  }  

This wrote the header that was required by the DataPower box.

How to use the class SecurityHeader

    public static void Main(string[] args)      {            var webService = new ServiceReference1.MyWebService();          ....         webService.Open();              using (OperationContextScope scope = new OperationContextScope((IContextChannel)webService.InnerChannel))          {                var myObjRequest = GetMyObjRequest();                MessageHeaders messageHeadersElement = OperationContext.Current.OutgoingMessageHeaders;              messageHeadersElement.Add(SecurityHeader("UserName", "Password"))                   var res = webService.MyServe(myObjRequest);              Console.WriteLine(res.ToString());          }      }  


Solution:2

Funny you should mention that - I've been doing exactly that recently.

I've managed to do it using a SoapExtension which uses ChainStream to keep a copy of the original stream, just copies the stream during BeforeDeserialize and adds the header during AfterSerialize.

Adding the header is a case of reading the contents of the "new" stream (returned from ChainStream) into an XML document (XDocument in my case), adding the header, and then writing it to the original stream passed into ChainStream.

Unfortunately this is pretty dirty, and you can't (as far as I'm aware) use a new instance with appropriate authentication information when you need to.

I've got most of the way using a SoapHeader instead, adding an appropriate attribute to each method of the web service and also an appropriate field/property with an instance of the required header - but the SOAP serialization is currently giving me headaches in terms of specifying the right element names (with namespaces). It's something I've been planning to ask others about when I get the time.

Sorry not to be able to give you a full answer - and also apologies for the lack of code, it belonging to the company rather than me - but hopefully it'll at least give you a starting point.


Solution:3

it's generally very easy to add a SOAP header to your web serivce proxy in .Net. Here's a quick code sample.

Create a new SOAP header

using System.Web.Services.Protocols;    public class SoapAuthHeader : SoapHeader  {  public string Username;  public string Password;  }  

In your web service proxy class:

public class MyWebServicesProxy : System.Web.Services.Protocols.SoapHttpClientProtocol {        public SoapAuthHeader AuthHeader;        ...    }  

And then to use:

SoapAuthHeader authHeader = new SoapAuthHeader();  authHeader.Username = "username";  authHeader.Password = "password";    MyWebServicesProxy myProxy = new MyWebServicesProxy();  myProxy.AuthHeader = authHeader;  

Edit: There are other ways to this and Microsoft do have a WSE library that includes WS-Security taht gives much more functionality then the simple sample above. If you need Kerberos tokens or certificate signing in your SOAP header then it's the way to go. if you jsut need to add a simple username and password for a web service operating over SSL then the exmaple may be all you need.

Edit: Quick blurb on WSE Earlier this decade when web services were going to take over the World a bunch of industry players (Microsoft, IBM, Sun etc.) got together to come up with standard ways of doing things over them. The body formed was OASIS. Since then Microsoft has released a number of versions of its WSE library to support some of the specifications but interestingly they've never been incorporated into the .Net framework even though the first version was made public around 2003.

Web services while still very popular and in my opinion a great way to integrate between different internet applications have gone a bit out of favour. One of the reasons is undoubtedly because AJAX and web services weren't the best of bed fellows, although that has improved. Web services also get pretty complicated once you start including all the additional sWSE specs and one of the thinge web services was suppossed to solve was the complexity in other RPC protocols, CORBA etc. In the meantime REST has gained a lot of popularity at the expense of Web Services and AJAX libraries often prefer it.

Web services aren't going to disappear soon by any means but they're probably not going to take over the World anytime soon either.


Solution:4

There is an open source custom Binding called ClearUserNameBinding, this binding helps passing UserNameToken as clearText on Http. This helped me out when a java based web service needed to be consumed using a WCF cllient.

http://code.google.com/p/wcf-clear-username-binding/ http://webservices20.blogspot.com/2008/11/introducing-wcf-clearusernamebinding.html


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »