Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Microsoft.Http.HttpClient, sending HTTP authentication parameters properly on redirects

Tags:

rest

c#

.net

http

i am making a request to a 3rd party RESTful service using Microsoft's HttpClient. It works flawlessly (and is very easy to implement) except for this one instance. Here is a breakdown from the provider as to what is occurring during the error:

"The way the POST to the group resource works is that when it completes, it does a HTTP 302 redirect to the group instance resource. What appears to be happening is that your HTTP Client is sending the proper authentication information to the POST, which creates the group resource, but when it handles the GET for the HTTP 302 request, it is not sending the right credentials and is getting a 401 response. Can you check your client library and make sure its sending HTTP auth parameters properly on redirects?"

Here is my POST code:

HttpClient http = new HttpClient(BASE_URL);
http.TransportSettings.Credentials = new NetworkCredential(ACCOUNT_SID, 
                                       ACCOUNT_TOKEN);
HttpResponseMessage httpResponse = http.Post(groupUri, "application/xml", 
                                       HttpContent.Create(xml.ToString()));
result = httpResponse.Content.ReadAsString();

Which brings me to my question; how do I get the authentication parameters to send on this GET redirect using the HttpClient class?

like image 413
Drew Avatar asked Jul 19 '10 15:07

Drew


1 Answers

I had a similar problem and at the end I added a form with a WebBrowser control. Whithout calling form.Show() I can tell him to navigate to an URL, click buttons and all. Here is the class that controls that form:

public class Nav
{
    FormNav formNav = new FormNav();
    public string Source
    {
        get
        {
            mshtml.HTMLDocument doc = (mshtml.HTMLDocument)formNav.webBrowser.Document.DomDocument;
            return doc.documentElement.innerHTML;
        }
    }

    public void GoTo(string Url)
    {
        formNav.webBrowser.Navigate(Url);
        Wait();
    }

    public void Fill(string Field, string Value)
    {
        formNav.webBrowser.Document.GetElementById(Field).InnerText = Value;
    }

    public void Click(string Element)
    {
        formNav.webBrowser.Document.GetElementById(Element).InvokeMember("click");
        Wait();
        Application.DoEvents();
    }

    public void Wait()
    {
        const int TIMEOUT = 30;

        formNav.Ready = false;
        DateTime start = DateTime.Now;
        TimeSpan span;

        do
        {
            Application.DoEvents();
            span = DateTime.Now.Subtract(start);
        } while (!formNav.Ready && span.Seconds < TIMEOUT);
    }

    public void Dispose()
    {
        formNav.Dispose();
    }
}

And here is the code for the form (some extra code is needed to disable the clicking sound).

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public partial class FormNav : Form
{
    private const int FEATURE_DISABLE_NAVIGATION_SOUNDS = 21;
    private const int SET_FEATURE_ON_THREAD = 0x00000001;
    private const int SET_FEATURE_ON_PROCESS = 0x00000002;
    private const int SET_FEATURE_IN_REGISTRY = 0x00000004;
    private const int SET_FEATURE_ON_THREAD_LOCALMACHINE = 0x00000008;
    private const int SET_FEATURE_ON_THREAD_INTRANET = 0x00000010;
    private const int SET_FEATURE_ON_THREAD_TRUSTED = 0x00000020;
    private const int SET_FEATURE_ON_THREAD_INTERNET = 0x00000040;
    private const int SET_FEATURE_ON_THREAD_RESTRICTED = 0x00000080;

    [DllImport("urlmon.dll")]
    [PreserveSig]
    [return: MarshalAs(UnmanagedType.Error)]
    static extern int CoInternetSetFeatureEnabled(
        int FeactureEntry,
        [MarshalAs(UnmanagedType.U4)] int dwFlags,
        bool fEnable);

    public bool Ready;

    public FormNav()
    {
        InitializeComponent();
        Ready = true;

        int feature = FEATURE_DISABLE_NAVIGATION_SOUNDS;
        CoInternetSetFeatureEnabled(feature, SET_FEATURE_ON_PROCESS, true);
    }

    private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        Ready = true;
    }
}

And the Microsoft Html Object COM Library should be added if the source code is needed.

like image 183
Jaime Oro Avatar answered Oct 21 '22 22:10

Jaime Oro