1

I'm trying to send some XML through HTTP Post. But I'm getting 401 Unauthorized. Funny thing is when I access the URL through the browser, the username/password I provide are OK.

Here is my method signature:

        internal static string Send(string URL, string XMLdata, string RequestMethod, 
                                    string RequestUsername, string RequestPassword)

I have tried this as method body:

        string requestData = XMLdata;
        string responseData = "";

        StreamWriter myWriter = null;
        HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(URL);

        objRequest.Method = RequestMethod;
        objRequest.PreAuthenticate = true;
        objRequest.ContentType = "application/x-www-form-urlencoded";//"text/xml";
        objRequest.Credentials = new NetworkCredential(RequestUsername, RequestPassword);;
        objRequest.ContentLength = requestData.Length;

        try
        {
            myWriter = new StreamWriter(objRequest.GetRequestStream());
            myWriter.Write(requestData);
        }
        finally
        {
            myWriter.Close();
        }

        StreamReader sr = null;

        try
        {
            HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
            sr = new StreamReader(objResponse.GetResponseStream());
            responseData = sr.ReadToEnd();
        }
        finally
        {
            if (sr != null)
                sr.Close();
        }

        return responseData;

And also this:

        string result;

        using (var client = new WebClient())
        {
            Uri requestUri = new Uri(URL);
            CredentialCache cache = new CredentialCache();
            NetworkCredential nc = new NetworkCredential(RequestUsername, RequestPassword);
            cache.Add(requestUri, "Basic", nc);
            client.Credentials = cache;

            result = client.UploadString(requestUri, XMLdata);
        }

        return result;

Both get the 401. What am I doing wrong? Just a reminder: when I access the URL through the browser, it prompts for username/password and the credentials I provide are OK.

My readings on the subject so far:

I appreciate the help.

Community
  • 1
  • 1
Adriano Carneiro
  • 57,693
  • 12
  • 90
  • 123
  • I don't have an answer for you, from your description, but I do have a suggestion: use Fiddler to see what the request and response look like, both when the browser request succeeds, and when the programmatic request fails. I suspect there will be a difference that jumps out at you. – jwismar May 24 '11 at 19:51
  • "it prompts for username/password" - in a popup window? Then it is Win auth. – Tomas Voracek May 24 '11 at 19:52
  • Yes, it prompts in a browser popup window, no matter what browser. Are you sure that makes this a Windows Authentication? Either way, do you know what I change in the codes I posted? – Adriano Carneiro May 24 '11 at 19:56
  • @jwismar Great tip, will do and let you know the outcome. BTW, you should post that as an answer – Adriano Carneiro May 24 '11 at 19:58
  • http://social.msdn.microsoft.com/forums/en-US/asmxandxml/thread/3ae9753d-2d97-45b9-9ba2-6d551fe60a48 "After a client request to a specific Uri is successfully authenticated. This means that the 1st time you send an HTTP request to a specific Uri, it is intentional that the request won't have an Authorization header." – Tomas Voracek May 24 '11 at 20:13
  • @Adrian: You're right, BASIC authentication pops up a message box, too. – jwismar May 24 '11 at 21:52
  • @Tomas: In .Net, the HttpWebRequest.PreAuthenticate property can be set so that even the first request sends credentials; I use that in cases where I know in advance I'm going to be sending the credentials anyway. – jwismar May 24 '11 at 21:54
  • @jwismar Can you share more specific info? Read http://www.west-wind.com/weblog/posts/2010/Feb/18/NET-WebRequestPreAuthenticate-not-quite-what-it-sounds-like, i've experienced same. But if you know more, i will be happy to know other ways. – Tomas Voracek May 24 '11 at 22:00
  • @Tomas: Interesting. I'm not using BASIC auth right now, so can't run a test, but I thought I recalled that it worked as advertised, and didn't recall the wrinkle that's described there. From that writeup, it still sounds like a valuable property to keep in mind, in terms of lessening the overall round-trips. – jwismar May 24 '11 at 22:07
  • I got it! I posted an answer below and thank everyone for taking the time to look at this – Adriano Carneiro May 25 '11 at 16:20
  • Maybe the authentication type is NTLM? – dolphy May 24 '11 at 19:49

2 Answers2

1

[At request of OP, I'm migrating my comment to an answer]

I don't have an answer for you, from your description, but I do have a suggestion: use Fiddler to see what the request and response look like, both when the browser request succeeds, and when the programmatic request fails. I suspect there will be a difference that jumps out at you.

jwismar
  • 12,164
  • 3
  • 32
  • 44
1

I solved it. Actually I was misled by the provider to make a mistake with the URL. The reason I'm posting my answer is for future reference, if someone ever comes across this.

The provider emailed me with the URL http://api.providersurl.com. When I get that into browser, it gets redirected to https://api.providersurl.com (HTTPS!). Then, I'm able to authorize with the credentials.

The funny thing that kept me banging my head against the wall is that by accessing the HTTP URL, I did not get 404 (Not Found) nor 302 (Redirect). I got 401 (Unauthorized). So I just kept trying! And boy, did I try...

When I changed the URL in the code to HTTPS, authorization worked with BOTH codes I posted.

It took a few hours... But no time is waste of time when you are learning a getting experienced.

Adriano Carneiro
  • 57,693
  • 12
  • 90
  • 123