locked
How to send credentials to ASMX service with Fiddler? RRS feed

  • Question

  • User-1526035670 posted

    Hi

    I followed this tutorial https://www.guru99.com/security-web-services.html to add basic authentication to an asmx webservice running under https (read only data).

    In short i added

    public class AuthHeader : SoapHeader
    {
    public string UserName;
    public string Password;

    }

    My method is surrounded with

    [SoapHeader("Credentials")]

    and the method includes

    if (Credentials.UserName == "username") && (Credentials.Password == "password"){
    // Get Data
    }

    When i run the service in a browser i see

    POST /MyServices.asmx HTTP/1.1
    Host: localhost
    Content-Type: text/xml; charset=utf-8
    Content-Length: length
    SOAPAction: "http://tempuri.org/GetData"

    <?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>
    <GetData xmlns="http://tempuri.org/" />
    </soap:Body>
    </soap:Envelope>

    I would like to use Fiddler to retrieve the data, so i create the POST request and the soap:Envelope to the header but it returns no data (probably due to the username/password not sent correctly).

    I then read up on clicking Tools > Text Wizard to enter the username and password in the format myusername:password which showed the value in BASE64 added

    Authentication: Basic BASE64StringForUsernamePassword

    but again this didnt work (again probably due to me doing something wrong).

    Does anyone know how i could send a request using Fiddler with a username and password? Or have i missed something somewhere else?

    Friday, May 15, 2020 10:22 AM

Answers

  • User475983607 posted

    I tried the tutorial and it just works.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    
    namespace AsmxDemo
    {
        /// <summary>
        /// Summary description for WebService1
        /// </summary>
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        [System.ComponentModel.ToolboxItem(false)]
        // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
        // [System.Web.Script.Services.ScriptService]
        public class MyServices : System.Web.Services.WebService
        {
            public AuthHeader Credentials;
    
            [SoapHeader("Credentials")]
            [WebMethod]
            public string HelloWorld()
            {
                if (Credentials.UserName.ToLower() != "username" || Credentials.Password.ToLower() != "password")
                {
                    throw new SoapException("Unauthorized", SoapException.ClientFaultCode);
                }
    
                return "Hello World";
            }
        }
    
        public class AuthHeader : SoapHeader
        {
            public string UserName;
            public string Password;
    
        }
    }
    

    I used PostMan to POST the SOAP message.

    <?xml version="1.0" encoding="utf-8"?>
    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
      <soap12:Header>
        <AuthHeader xmlns="http://tempuri.org/">
          <UserName>username</UserName>
          <Password>password</Password>
        </AuthHeader>
      </soap12:Header>
      <soap12:Body>
        <HelloWorld xmlns="http://tempuri.org/" />
      </soap12:Body>
    </soap12:Envelope>

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, May 15, 2020 12:23 PM

All replies

  • User475983607 posted

    You are not using basic authentication, at least the tutorial does not configure basic authentication in IIS. 

    It seems you have the proper XML but it is not clear if you replaced "string" the correct username and password.  Are you using the Visual Studio debugger?  Is the GetData method hit?  Does the server return an authentication error? 

    Have you tried creating a service reference?  

    Friday, May 15, 2020 10:40 AM
  • User-1526035670 posted

    mgebhard

    You are not using basic authentication, at least the tutorial does not configure basic authentication in IIS. 

    It seems you have the proper XML but it is not clear if you replaced "string" the correct username and password.  Are you using the Visual Studio debugger?  Is the GetData method hit?  Does the server return an authentication error? 

    Have you tried creating a service reference?  

    Hi

    Yes, using VS, ive not configured anything else at this moment.

    In Fiddler the only way i assume i have sent the username and password is using the BASE64 string, which i feel is now incorrect.

    With that said i noticed an error which i have only discovered, when calling the service from a browser and having debug enabled (stepping through the code)

    if (Credentials.UserName == "username") && (Credentials.Password == "password"){
    // Get Data
    }

    GetData is not hit as Credentials is null (Object is not set to an instance). Re-done that code to

    Credentials = new AuthHeader();

    but the same error is hit. I must be doing something wrong within the service, perhaps?

    Friday, May 15, 2020 10:48 AM
  • User475983607 posted

    I tried the tutorial and it just works.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    
    namespace AsmxDemo
    {
        /// <summary>
        /// Summary description for WebService1
        /// </summary>
        [WebService(Namespace = "http://tempuri.org/")]
        [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
        [System.ComponentModel.ToolboxItem(false)]
        // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
        // [System.Web.Script.Services.ScriptService]
        public class MyServices : System.Web.Services.WebService
        {
            public AuthHeader Credentials;
    
            [SoapHeader("Credentials")]
            [WebMethod]
            public string HelloWorld()
            {
                if (Credentials.UserName.ToLower() != "username" || Credentials.Password.ToLower() != "password")
                {
                    throw new SoapException("Unauthorized", SoapException.ClientFaultCode);
                }
    
                return "Hello World";
            }
        }
    
        public class AuthHeader : SoapHeader
        {
            public string UserName;
            public string Password;
    
        }
    }
    

    I used PostMan to POST the SOAP message.

    <?xml version="1.0" encoding="utf-8"?>
    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
      <soap12:Header>
        <AuthHeader xmlns="http://tempuri.org/">
          <UserName>username</UserName>
          <Password>password</Password>
        </AuthHeader>
      </soap12:Header>
      <soap12:Body>
        <HelloWorld xmlns="http://tempuri.org/" />
      </soap12:Body>
    </soap12:Envelope>

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, May 15, 2020 12:23 PM
  • User-1526035670 posted

    Hi

    Appreciate you taking the time to help here. Im still trying with Fiddler and before i download and install Postman this is what i have under Composer

    Host: localhost:1122
    Connection: keep-alive
    Content-Length: 0
    Cache-Control: max-age=0
    Upgrade-Insecure-Requests: 1
    Origin: http://localhost:1122
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Sec-Fetch-Site: same-origin
    Sec-Fetch-Mode: navigate
    Sec-Fetch-User: ?1
    Sec-Fetch-Dest: document
    Referer: http://localhost:1122/MyServices.asmx?op=GetData
    Accept-Encoding: gzip, deflate, br
    Accept-Language: en-GB,en;q=0.9,fr;q=0.8,en-US;q=0.7
    Cookie: ASP.NET_SessionId=eoqwlbuqqymlpkjvg4drsxvi; _ga=GA1.1.712628692.1589274334; _hjid=ff87d18b-0af0-4003-b957-6842a59ccfa7; _hjIncludedInSample=1; WaltonClient=cf5e63aa-68dd-41ad-99e5-9bf609a9f253-2204346; __atuvc=0%7C16%2C0%7C17%2C0%7C18%2C0%7C19%2C3%7C20 
    Credentials: Basic USERNAME:PASSWORD_IN_BASE64==

    Could you compare this with what you sent in Postman, to see if i can narrow down whats going on? If not i will install PM and try again.

    Many thanks

    Friday, May 15, 2020 1:58 PM
  • User475983607 posted

    There are several issues with request.  The content-length is zero,  content-type should be application/soap+xml; charset=utf-8 or text/xml; charset=utf-8, the Url should have the have the asmx file.

    Just get PostMan.  It's much easier than fiddlers.  Secondly, you'll never write SOAP messages manually.

    Friday, May 15, 2020 2:34 PM
  • User-1526035670 posted

    Right, i have PM and it does seem easier.... anyway I create a GET request (im getting the data (GetData) where i pass in a username and password) but i might be doing something wrong.

    In a web browser i go to http://localhost:1122/MyServices.asmx?op=GetData
    I see the service and click invoke, which returns back empty as i dont have a username/password sent. This is ok.

    I do the same in PM enter the above address, i now enter the username and password in the applicable field but in the preview pane all i see is the landing page and i cant invoke the service? It doesnt hit my debug point either?

    Friday, May 15, 2020 2:58 PM
  • User475983607 posted

    anyway I create a GET request (im getting the data (GetData) where i pass in a username and password) but i might be doing something wrong.

    It has to be a POST.  HTTP GET does not have an message body.  Make sure you add a  content-type header and set it to application/soap+xml; charset=utf-8.

    Friday, May 15, 2020 3:27 PM
  • User-1526035670 posted

    Now that i have that working, it worked in a different manner to what i originally anticipated. Using the XML from the schema i passed in the appropriate values which triggered the service authentication system - Thank you on that.

    Would this mean when i need to consume this service via C# code, i would create an instance of my service and then pass in the credentials as below?

    myService.ClientCredentials.UserName.UserName = "username";
    myService.ClientCredentials.UserName.Password = "password";
    
    

    As long as the method is surrounded by 

    [SoapHeader("Credentials")]
    Friday, May 15, 2020 4:04 PM
  • User475983607 posted

    Would this mean when i need to consume this service via C# code, i would create an instance of my service and then pass in the credentials as below?

    myService.ClientCredentials.UserName.UserName = "username";
    myService.ClientCredentials.UserName.Password = "password";
    

    As long as the method is surrounded by 

    [SoapHeader("Credentials")]

    No.  Create a service reference.  Instantiate the service and populate AuthHeader type.   

    ServiceReference2.MyServicesSoapClient client = new ServiceReference2.MyServicesSoapClient();
    ServiceReference2.AuthHeader auth = new ServiceReference2.AuthHeader()
    {
        UserName = "username",
        Password = "password"
    };
    
    string results = client.HelloWorld(auth);

    It really helps if you go through getting started tutorials or read the reference documentation rather than guessing.

    Friday, May 15, 2020 4:44 PM