How to use HttpClient to Post with Authentication

78,274

Solution 1

First you have to set the Authorization-Header with your <clientid> and <clientsecret>.

Instead of using StringContent you should use FormUrlEncodedContent as shown below:

var client = new HttpClient();
client.BaseAddress = new Uri("http://myserver");
var request = new HttpRequestMessage(HttpMethod.Post, "/path");

var byteArray = new UTF8Encoding().GetBytes("<clientid>:<clientsecret>");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

var formData = new List<KeyValuePair<string, string>>();
formData.Add(new KeyValuePair<string, string>("grant_type", "password"));
formData.Add(new KeyValuePair<string, string>("username", "<email>"));
formData.Add(new KeyValuePair<string, string>("password", "<password>"));
formData.Add(new KeyValuePair<string, string>("scope", "all"));

request.Content = new FormUrlEncodedContent(formData);
var response = await client.SendAsync(request);

Solution 2

Try to place your credentials directly into the headers property of HttpClient.

using (var client = new HttpClient()) {
       var byteArray = Encoding.ASCII.GetBytes("my_client_id:my_client_secret");
       var header = new AuthenticationHeaderValue("Basic",Convert.ToBase64String(byteArray));
       client.DefaultRequestHeaders.Authorization = header;

       return await client.GetStringAsync(uri);
}

Solution 3

See BasicAuthenticationHeaderValue

httpClient.DefaultRequestHeaders.Authorization
    = new BasicAuthenticationHeaderValue("login", "password");
Share:
78,274
Jesse
Author by

Jesse

Updated on March 26, 2021

Comments

  • Jesse
    Jesse about 3 years

    I am trying to do the following curl (which works for me) in C# using HttpClient.

    curl -X POST http://www.somehosturl.com \
         -u <client-id>:<client-secret> \
         -d 'grant_type=password' \
         -d 'username=<email>' \
         -d 'password=<password>' \
         -d 'scope=all
    

    The C# Code:

    HttpClientHandler handler = new HttpClientHandler { Credentials = new  
                System.Net.NetworkCredential ("my_client_id", "my_client_secret")
        };
    
    
        try
        {
            using(var httpClient = new HttpClient(handler))
            {
                var activationUrl = "www.somehosturl.com";
    
                var postData = "grant_type=password&[email protected]&password=mypass&scope=all";
                var content = new StringContent(postData, Encoding.UTF8, "application/x-www-form-urlencoded");
    
                var response = await httpClient.PostAsync(activationUrl, content);
                if(!response.IsSuccessStatusCode)
                    return null;
    
                var result = await response.Content.ReadAsStringAsync();
    
                return result;
            }
        }
        catch(Exception)
        {
            return null;
        }
    

    When executed, just crashes out, doesnt even catch the exception

    Normally I am able to GET and POST perfectly fine, but whats throwing me off is how to set the auth stuff (client-id and client-secret)

  • Panagiotis Kanavos
    Panagiotis Kanavos almost 9 years
    You should explain why this is an answer to the question. Do you want to say that on top of having to set the authentication header, the OP passes post data in the wrong way ?
  • Jesse
    Jesse almost 9 years
    Thanks Alexander, this works great! I am using Xamarin though so I couldn't use Encoding.ASCII, I had to use new UTF8Encoding().GetBytes().
  • Richard Marskell - Drackir
    Richard Marskell - Drackir over 5 years
    Why do you use client.DefaultRequestHeaders.Authorization instead of request.Headers.Authorization?
  • Mikołaj
    Mikołaj over 2 years
    You've written about BasicAuthenticationHeaderValue but provided link to AuthenticationHeaderValue, so your example is invalid in .Net 5.
  • dellos
    dellos about 2 years
    Can someone explain why need to change data to byteArray before passing to client.DefaultRequestHeaders.Authorization ?
  • dellos
    dellos about 2 years
    Can someone explain why need to change data to byteArray before passing to client.DefaultRequestHeaders.Authorization ?
  • Alexander Zeitler
    Alexander Zeitler about 2 years
    @dellos Because Convert.ToBase64String() has no overload which accepts a string value. docs.microsoft.com/en-us/dotnet/api/…
  • dellos
    dellos about 2 years
    @AlexanderZeitler, No I thought about why need to cast the "<clientid>:<clientsecret>" string to byteArray first then cast it back to string? Is it for a security concert?
  • Alexander Zeitler
    Alexander Zeitler about 2 years
    @dellos The second cast is not a plain text string but a base64 encoded one. en.wikipedia.org/wiki/Basic_access_authentication