Dheeraj
Dheeraj

Reputation: 326

authentication for a Web service options

I am new to Web services and .NET. I have to authenticate a web service that is being accessed using http post.

I tried putting a custom soap header and sending it to the service and checking the header in service but the header object is always null in the service.

also if i put the user and password options in http headers how can i validate them on the server ?

Thanks in advance

Client code:

 private void button1_Click(object sender, EventArgs e)
        {
           HttpWebRequest request;

           string strSOAPRequestBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
           "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"+
           "<soap:Header>"+
           "<AuthHeader xmlns=\"http://tempuri.org/\">" +
           "<Username>apple</Username>"+
           "<Password>apple</Password>"+
           "</AuthHeader>"+
           "</soap:Header>"+
           "<soap:Body xmlns=\"http://tempuri.org/\">"+
           "<HelloWorld>"+
           "</soap:Body>"+
           "</soap:Envelope>";

           request = (HttpWebRequest)WebRequest.Create("http://localhost:1494/Service1.asmx/HelloWorld");
           request.Accept = "text/xml";
           request.Method = "POST";
           request.ContentType = "application/soap+xml; charset=utf-8";
           request.ContentLength = strSOAPRequestBody.Length;


           using (Stream stream = request.GetRequestStream())
           {
               using (StreamWriter sw = new StreamWriter(stream))
               {
                   sw.Write(strSOAPRequestBody);
                   sw.Flush();
               }
           }
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
           {
               using (StreamReader responseStream = new StreamReader(response.GetResponseStream()))
               {
                  txtResponse.Text = System.Web.HttpUtility.HtmlDecode(responseStream.ReadToEnd());
               }
           }
        } 

Service

public class Service1 : System.Web.Services.WebService
    {


        public AuthHeader Authentication;

        [WebMethod]
        [SoapHeader("Authentication", Direction = SoapHeaderDirection.In)]
         public XmlDocument HelloWorld()
        {
            XmlDocument response = new XmlDocument();
            try
            {

                //Boolean validateUser = Membership.ValidateUser(Authentication.Username, Authentication.Password);
                if (Authentication != null)
                {
                    response.LoadXml(String.Format("{0}{1}{2}", "<BOM>", "Hurray", "</BOM>"));
                }

            }
            catch( Exception ex)
            {
                response.LoadXml(String.Format("{0}{1}{2}", "<Error>", ex.Message, "</Error>"));
            }
                return response;
        }
    }

Upvotes: 0

Views: 2191

Answers (1)

Randy Levy
Randy Levy

Reputation: 22655

The problem is with the client code:

  • Set the URI to the service URI (i.e. the asmx file)
  • Add the soap action as a header (i.e. HelloWorld)
  • Set the content type as text/xml
  • Change the soap request to include the namespace on the soap method and not the body element

Try this:

HttpWebRequest request;

string strSOAPRequestBody = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
"  <soap:Header>" +
"    <AuthHeader xmlns=\"http://tempuri.org/\">" +
"      <Username>string</Username>" +
"      <Password>string</Password>" +
"    </AuthHeader>" +
"  </soap:Header>" +
"  <soap:Body>" +
"    <HelloWorld xmlns=\"http://tempuri.org/\" />" +
"  </soap:Body>" +
"</soap:Envelope>";

request = (HttpWebRequest)WebRequest.Create("http://localhost:1494/Service1.asmx");
request.Accept = "text/xml";
request.Method = "POST";
request.ContentType = "text/xml;charset=\"utf-8\"";
request.Headers.Add("SOAPAction", "\"http://tempuri.org/HelloWorld\"");    
request.ContentLength = strSOAPRequestBody.Length;

using (Stream stream = request.GetRequestStream())
{
    using (StreamWriter sw = new StreamWriter(stream))
    {
        sw.Write(strSOAPRequestBody);
        sw.Flush();
    }
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    using (StreamReader responseStream = new StreamReader(response.GetResponseStream()))
    {
        Console.WriteLine((responseStream.ReadToEnd()));
    }
}

If you do that you should receive the response:

<?xml version="1.0" encoding="utf-8"?>
  <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">     
    <soap:Body><HelloWorldResponse xmlns="http://tempuri.org/">
      <HelloWorldResult>
        <BOM xmlns="">Hurray</BOM>
      </HelloWorldResult>
    </HelloWorldResponse>
  </soap:Body>
</soap:Envelope>

To validate the username and password would depend on your implementation -- if you have asp.net membership then you should be able to use the ValidateUser method. Also note that if you are not using SSL then the username and password will be visible when sent over the wire.

Another note is that hand crafting XML as a string is almost always a bad idea so (at the very least) use XML framework classes to generate proper XML. Even better is to use web service toolkit.

Upvotes: 2

Related Questions