Establecer el encabezado de autorización de HttpClient

483

Tengo un HttpClient que estoy usando para una API REST. Sin embargo, tengo problemas para configurar el encabezado de autorización. Necesito establecer el encabezado en el token que recibí al hacer mi solicitud de OAuth. Vi un código para .NET que sugiere lo siguiente,

httpClient.DefaultRequestHeaders.Authorization = new Credential(OAuth.token);

Sin embargo, la clase Credential no existe en WinRT. ¿Alguien tiene alguna idea de cómo configurar el encabezado de autorización?

Stephen Hynes
fuente
1
¿A qué espacio de nombres pertenece la clase Credential?
kampsj
@kampsj No lo sé ya que es un espacio de nombres .NET que no existe en WinRT
Stephen Hynes
1
¿Por qué no request.Headers.Add ("Autorización", token);
ahll

Respuestas:

817

Entonces la forma de hacerlo es la siguiente,

httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "Your Oauth token");
Stephen Hynes
fuente
16
¿Cómo obtienes "Tu token Oauth"?
Secret Squirrel
3
Lo que he usado es: client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "encrypted user/pwd");Tomar un usuario cifrado / pwd de la extensión de Chrome Advanced Rest Client.
Rojo
66
@ Para su información, el segundo parámetro es el usuario codificado en base64: contraseña (no está encriptada).
n00b
55
Mi aplicación estaba feliz de usar esto durante años, luego, de la nada, comencé a recibir una RuntimeBinderException. Tuve que cambiar a httpClient.DefaultRequestHeaders.Add ("Autorización", "Portador", "Tu token Oauth"); para que vuelva a funcionar.
kraeg
8
@kraeg, el código que enumeró no se compila, ¿quiso concatenar las últimas 2 cadenas de la siguiente manera: client.DefaultRequestHeaders.Add ("Autorización", "Portador" + "Su token Oauth");
TroySteven
354
request.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue(
        "Basic", Convert.ToBase64String(
            System.Text.ASCIIEncoding.ASCII.GetBytes(
               $"{yourusername}:{yourpwd}")));
TheWhiteRabbit
fuente
27
@MickyDuncan HttpClient tiene una DefaultRequestHeaders.Authorization. Y esta respuesta me salvó el día. Muchas gracias a WhiteRabbit.
Joey Schluchter
3
Esto no funciona, si inspecciona el encabezado Auhtorization no contiene más que una cadena Basic.
Raffaeu
1
¿Alguien puede explicar por qué es importante convertir el nombre de usuario y la contraseña en una cadena base64? No ofrece cifrado real, entonces, ¿por qué eso importa?
Jonathan Wood
3
@ JonathanWood Porque así es cómo se define para ser utilizado. Basic no ofrece cifrado, solo codificación suficiente para evitar problemas con la elección de caracteres de contraseña en un encabezado.
Richard
44
¿Hay alguna razón particular por la que usaste codificación ASCII aquí? Supongo que no hay problema con el uso de la codificación UTF8 ya que de todos modos estamos codificando Base64. Supongo que me pregunto si la especificación de autenticación básica dice que el combo nombre de usuario: contraseña debería estar solo en ASCII.
aplastar
82

Busco una buena manera de abordar este problema y estoy viendo la misma pregunta. Con suerte, esta respuesta ayudará a todos los que tienen el mismo problema que les gusto.

using (var client = new HttpClient())
{
    var url = "https://www.theidentityhub.com/{tenant}/api/identity/v1";
    client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
    var response = await client.GetStringAsync(url);
    // Parse JSON response.
    ....
}

referencia de https://www.theidentityhub.com/hub/Documentation/CallTheIdentityHubApi

Willie Cheng
fuente
1
Estoy haciendo exactamente lo mismo @willie y todavía obtengo un 401 de mi API
algo el
2
Hola @SomethingOn Creo que no obtuviste una clave de token correcta, por lo que obtuviste 401, compartiré mi camino en mi "Pregunta" personal, espero que pueda ayudarte a lidiar con tu problema. PS esperando un momento
Willie Cheng
14
No deberías poner un HttpClient en un usingbloque. (Sí, sé que suena al revés, pero perderá las conexiones si usa en usinglugar de simplemente reciclar el HttpClient.)
Jonathan Allen
42

Como es una buena práctica reutilizar la instancia de HttpClient , para problemas de rendimiento y agotamiento de puertos , y debido a que ninguna de las respuestas da esta solución (e incluso lo lleva a malas prácticas :(), pongo aquí un enlace hacia la respuesta que hice en una pregunta similar:

https://stackoverflow.com/a/40707446/717372

Algunas fuentes sobre cómo usar HttpClient de la manera correcta:

Philippe
fuente
55
El problema del agotamiento del puerto no es broma. Casi nunca sucede en el control de calidad, pero afectará a cualquier proyecto muy utilizado en producción.
Jonathan Allen
Vea mi publicación para un ejemplo concreto stackoverflow.com/a/59052193/790635
emp
41

Estoy de acuerdo con la respuesta de TheWhiteRabbit, pero si tiene muchas llamadas usando HttpClient, el código parece un poco repetitivo en mi opinión.

Creo que hay 2 formas de mejorar un poco la respuesta.

Cree una clase auxiliar para crear el cliente:

public static class ClientHelper
{
    // Basic auth
    public static HttpClient GetClient(string username,string password)
    {
            var authValue = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}")));

            var client = new HttpClient(){
                DefaultRequestHeaders = { Authorization = authValue}
                //Set some other client defaults like timeout / BaseAddress
            };
            return client;
    }

    // Auth with bearer token
    public static HttpClient GetClient(string token)
    {
            var authValue = new AuthenticationHeaderValue("Bearer", token);

            var client = new HttpClient(){
                DefaultRequestHeaders = { Authorization = authValue}
                //Set some other client defaults like timeout / BaseAddress
            };
            return client;
    }
}

Uso:

using(var client = ClientHelper.GetClient(username,password))
{
    //Perform some http call
}

using(var client = ClientHelper.GetClient(token))
{
    //Perform some http call
}

Crea un método de extensión:

No gana un premio de belleza pero funciona muy bien :)

    public static class HttpClientExtentions
    {
        public static AuthenticationHeaderValue ToAuthHeaderValue(this string username, string password)
        {
            return new AuthenticationHeaderValue("Basic",
        Convert.ToBase64String(
            System.Text.Encoding.ASCII.GetBytes(
                $"{username}:{password}")));
        }
    }

Uso:

using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Authorization = _username.ToAuthHeaderValue(_password); 
}

Nuevamente, creo que las 2 opciones anteriores hacen que el cliente que usa la declaración sea un poco menos repetitivo. Tenga en cuenta que es una buena práctica reutilizar el HttpClient si está haciendo varias llamadas http, pero creo que está un poco fuera de alcance para esta pregunta.

Florian Schaal
fuente
20
puedo ver que su respuesta está votada, pero no recomendaría este enfoque TL; DR es simplemente incorrecto porque el agotamiento del socket, aquí está el enlace de
lacripta
2
@lacripta, esto es cierto, pero si lees las últimas 2 oraciones, digo que es una buena práctica reutilizar HttpClient exactamente por esta razón, pero creo que está fuera del alcance de esta pregunta.
Florian Schaal
1
puedo ver su punto pero está haciendo una sugerencia diciendo que el código es repetitivo, esto podría conducir al mal uso de este método de fábrica, sería bueno señalar en las primeras líneas que causará problemas de uso de recursos en el futuro especialmente para este caso. y no solo una advertencia que la mayoría no leerá.
lacripta
1
Usar HttpClientFactory sería mucho mejor para evitar el problema del agotamiento del socket.
RyanOC
21

Estaba configurando la ficha de portador

httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

Funcionaba en un punto final, pero no en otro. El problema era que tenía minúsculas ben"bearer" . Después del cambio ahora funciona para las dos API que estoy golpeando. Es algo tan fácil de perder si ni siquiera lo está considerando como uno de los pajaros para buscar la aguja.

Asegúrese de tener "Bearer"- con capital.

Alan Ball
fuente
18

Te sugiero:

HttpClient.DefaultRequestHeaders.Add("Authorization", "Bearer <token>");

Y luego puedes usarlo así:

var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
    responseMessage = await response.Content.ReadAsAsync<ResponseMessage>();
}
Amankhani MohammadJavad
fuente
Si su token se agota cada 1 hora, por ejemplo, debe actualizar el HttpClient con esta solución. Sugeriría comprobar que su token sigue siendo válido y, de lo contrario, actualizarlo y agregarlo al HttpRequestMessage
Johan Franzén
13

Para configurar la autenticación básica con C # HttpClient. El siguiente código me funciona.

   using (var client = new HttpClient())
        {
            var webUrl ="http://localhost/saleapi/api/";
            var uri = "api/sales";
            client.BaseAddress = new Uri(webUrl);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.ConnectionClose = true;

            //Set Basic Auth
            var user = "username";
            var password = "password";
            var base64String =Convert.ToBase64String( Encoding.ASCII.GetBytes($"{user}:{password}"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",base64String);

            var result = await client.PostAsJsonAsync(uri, model);
            return result;
        }
LENG UNG
fuente
Exactamente lo que necesitaba, gracias.
rchrd
10

Así es como lo he hecho:

using (HttpClient httpClient = new HttpClient())
{
   Dictionary<string, string> tokenDetails = null;
   var messageDetails = new Message { Id = 4, Message1 = des };
   HttpClient client = new HttpClient();
   client.BaseAddress = new Uri("http://localhost:3774/");
   var login = new Dictionary<string, string>
       {
           {"grant_type", "password"},
           {"username", "[email protected]"},
           {"password", "lopzwsx@23"},
       };
   var response = client.PostAsync("Token", new FormUrlEncodedContent(login)).Result;
   if (response.IsSuccessStatusCode)
   {
      tokenDetails = JsonConvert.DeserializeObject<Dictionary<string, string>>(response.Content.ReadAsStringAsync().Result);
      if (tokenDetails != null && tokenDetails.Any())
      {
         var tokenNo = tokenDetails.FirstOrDefault().Value;
         client.DefaultRequestHeaders.Add("Authorization", "Bearer " + tokenNo);
         client.PostAsJsonAsync("api/menu", messageDetails)
             .ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode());
      }
   }
}

Este video de you-tube me ayudó mucho. Por favor, míralo. https://www.youtube.com/watch?v=qCwnU06NV5Q

Dayan
fuente
9

Utilice la autorización básica y los parámetros de Json.

using (HttpClient client = new HttpClient())
                    {
                        var request_json = "your json string";

                        var content = new StringContent(request_json, Encoding.UTF8, "application/json");

                        var authenticationBytes = Encoding.ASCII.GetBytes("YourUsername:YourPassword");

                        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
                               Convert.ToBase64String(authenticationBytes));
                        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                        var result = await client.PostAsync("YourURL", content);

                        var result_string = await result.Content.ReadAsStringAsync();
                    }
MohammadSoori
fuente
2
No debe incluir código para deshabilitar la comprobación de certificados SSL en un ejemplo como este. Las personas pueden copiar ciegamente su código sin darse cuenta de lo que hace. He eliminado esas líneas por ti.
John
9

Si desea reutilizar el HttpClient, se recomienda no utilizar elDefaultRequestHeaders como se utilizan para enviar con cada solicitud.

Podrías probar esto:

var requestMessage = new HttpRequestMessage
    {
        Method = HttpMethod.Post,
        Content = new StringContent("...", Encoding.UTF8, "application/json"),
        RequestUri = new Uri("...")
    };

requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic", 
    Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"{user}:{password}")));

var response = await _httpClient.SendAsync(requestMessage);
emp
fuente
8

6 años después, pero agregando esto en caso de que ayude a alguien.

https://www.codeproject.com/Tips/996401/Authenticate-WebAPIs-with-Basic-and-Windows-Authen

var authenticationBytes = Encoding.ASCII.GetBytes("<username>:<password>");
using (HttpClient confClient = new HttpClient())
{
  confClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", 
         Convert.ToBase64String(authenticationBytes));
  confClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Constants.MediaType));  
  HttpResponseMessage message = confClient.GetAsync("<service URI>").Result;
  if (message.IsSuccessStatusCode)
  {
    var inter = message.Content.ReadAsStringAsync();
    List<string> result = JsonConvert.DeserializeObject<List<string>>(inter.Result);
  }
}
MPJ567
fuente
Trabajó para mi. A diferencia de la respuesta de Willie Cheng, que no funcionó para mí.
user890332
5

Opción UTF8

request.DefaultRequestHeaders.Authorization = 
new AuthenticationHeaderValue(
    "Basic", Convert.ToBase64String(
        System.Text.Encoding.UTF8.GetBytes(
           $"{yourusername}:{yourpwd}")));
romelmederos
fuente
3

Usando AuthenticationHeaderValueclase de System.Net.Httpensamblaje

public AuthenticationHeaderValue(
    string scheme,
    string parameter
)

podemos configurar o actualizar el Authorizationencabezado existente para nuestro me httpclientgusta así:

httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TokenResponse.AccessToken);
Fusión
fuente
1
Bienvenido a SO, pero agrega un poco más de contexto.
JP Hellemons
La respuesta es acertada, pero no estaría de más tener una frase que explique lo que se supone que debe hacer su código. Solo digo.
iiminov
2

BaseWebApi.cs

public abstract class BaseWebApi
{
    //Inject HttpClient from Ninject
    private readonly HttpClient _httpClient;
    public BaseWebApi(HttpClient httpclient)
    {
        _httpClient = httpClient;
    }

    public async Task<TOut> PostAsync<TOut>(string method, object param, Dictionary<string, string> headers, HttpMethod httpMethod)
    {
        //Set url

        HttpResponseMessage response;
        using (var request = new HttpRequestMessage(httpMethod, url))
        {
            AddBody(param, request);
            AddHeaders(request, headers);
            response = await _httpClient.SendAsync(request, cancellationToken);
        }

        if(response.IsSuccessStatusCode)
        {
             return await response.Content.ReadAsAsync<TOut>();
        }
        //Exception handling
    }

    private void AddHeaders(HttpRequestMessage request, Dictionary<string, string> headers)
    {
        request.Headers.Accept.Clear();
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        if (headers == null) return;

        foreach (var header in headers)
        {
            request.Headers.Add(header.Key, header.Value);
        }
    }

    private static void AddBody(object param, HttpRequestMessage request)
    {
        if (param != null)
        {
            var content = JsonConvert.SerializeObject(param);
            request.Content = new StringContent(content);
            request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
    }

SubWebApi.cs

public sealed class SubWebApi : BaseWebApi
{
    public SubWebApi(HttpClient httpClient) : base(httpClient) {}

    public async Task<StuffResponse> GetStuffAsync(int cvr)
    {
        var method = "get/stuff";
        var request = new StuffRequest 
        {
            query = "GiveMeStuff"
        }
        return await PostAsync<StuffResponse>(method, request, GetHeaders(), HttpMethod.Post);
    }
    private Dictionary<string, string> GetHeaders()
    {
        var headers = new Dictionary<string, string>();
        var basicAuth = GetBasicAuth();
        headers.Add("Authorization", basicAuth);
        return headers;
    }

    private string GetBasicAuth()
    {
        var byteArray = Encoding.ASCII.GetBytes($"{SystemSettings.Username}:{SystemSettings.Password}");
        var authString = Convert.ToBase64String(byteArray);
        return $"Basic {authString}";
    }
}
Joel Wiklund
fuente
1

En el caso de que desee enviar una HttpClientsolicitud con Token de portador, este código puede ser una buena solución:

var requestMessage = new HttpRequestMessage
{
    Method = HttpMethod.Post,
    Content = new StringContent(".....", Encoding.UTF8, "application/json"),
    RequestUri = new Uri(".....")
};

requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "Your token");

var response = await _httpClient.SendAsync(requestMessage);
Jourmand
fuente
0

En net .core puedes usar

var client = new HttpClient();
client.SetBasicAuthentication(userName, password);

o

var client = new HttpClient();
client.SetBearerToken(token);
Thom Kiesewetter
fuente
1
El primer ejemplo no funciona ya SetBasicAuthentication()que no está disponible por defecto, por lo que debe ser un método de extensión. ¿Dónde se define?
ViRuSTriNiTy
0

Puede ser más fácil usar una biblioteca existente.

Por ejemplo, los siguientes métodos de extensión se agregan con Identity Server 4 https://www.nuget.org/packages/IdentityModel/

 public static void SetBasicAuthentication(this HttpClient client, string userName, string password);
    //
    // Summary:
    //     Sets a basic authentication header.
    //
    // Parameters:
    //   request:
    //     The HTTP request message.
    //
    //   userName:
    //     Name of the user.
    //
    //   password:
    //     The password.
    public static void SetBasicAuthentication(this HttpRequestMessage request, string userName, string password);
    //
    // Summary:
    //     Sets a basic authentication header for RFC6749 client authentication.
    //
    // Parameters:
    //   client:
    //     The client.
    //
    //   userName:
    //     Name of the user.
    //
    //   password:
    //     The password.
    public static void SetBasicAuthenticationOAuth(this HttpClient client, string userName, string password);
    //
    // Summary:
    //     Sets a basic authentication header for RFC6749 client authentication.
    //
    // Parameters:
    //   request:
    //     The HTTP request message.
    //
    //   userName:
    //     Name of the user.
    //
    //   password:
    //     The password.
    public static void SetBasicAuthenticationOAuth(this HttpRequestMessage request, string userName, string password);
    //
    // Summary:
    //     Sets an authorization header with a bearer token.
    //
    // Parameters:
    //   client:
    //     The client.
    //
    //   token:
    //     The token.
    public static void SetBearerToken(this HttpClient client, string token);
    //
    // Summary:
    //     Sets an authorization header with a bearer token.
    //
    // Parameters:
    //   request:
    //     The HTTP request message.
    //
    //   token:
    //     The token.
    public static void SetBearerToken(this HttpRequestMessage request, string token);
    //
    // Summary:
    //     Sets an authorization header with a given scheme and value.
    //
    // Parameters:
    //   client:
    //     The client.
    //
    //   scheme:
    //     The scheme.
    //
    //   token:
    //     The token.
    public static void SetToken(this HttpClient client, string scheme, string token);
    //
    // Summary:
    //     Sets an authorization header with a given scheme and value.
    //
    // Parameters:
    //   request:
    //     The HTTP request message.
    //
    //   scheme:
    //     The scheme.
    //
    //   token:
    //     The token.
    public static void SetToken(this HttpRequestMessage request, string scheme, string token);
Lee Smith
fuente
0

Oauth El flujo del proceso es complejo y siempre hay espacio para un error u otro. Mi sugerencia será utilizar siempre el código repetitivo y un conjunto de bibliotecas para el flujo de autenticación OAuth. Le facilitará la vida.

Aquí está el enlace para el conjunto de bibliotecas. Bibliotecas OAuth para .Net

Khurram Jamil
fuente
-1

esto podría funcionar, si está recibiendo un json o un xml del servicio y creo que esto puede darle una idea sobre cómo funcionan los encabezados y el tipo T también, si usa la función MakeXmlRequest (poner los resultados en xmldocumnet) y MakeJsonRequest (ponga el json en la clase que desee que tenga la misma estructura que la respuesta json) de la siguiente manera

/*-------------------------example of use-------------*/
MakeXmlRequest<XmlDocument>("your_uri",result=>your_xmlDocument_variable =     result,error=>your_exception_Var = error);

MakeJsonRequest<classwhateveryouwant>("your_uri",result=>your_classwhateveryouwant_variable=result,error=>your_exception_Var=error)
/*-------------------------------------------------------------------------------*/


public class RestService
{
    public void MakeXmlRequest<T>(string uri, Action<XmlDocument> successAction, Action<Exception> errorAction)
    {
        XmlDocument XMLResponse = new XmlDocument();
        string wufooAPIKey = ""; /*or username as well*/
        string password = "";
        StringBuilder url = new StringBuilder();
        url.Append(uri);
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url.ToString());
        string authInfo = wufooAPIKey + ":" + password;
        authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
        request.Timeout = 30000;
        request.KeepAlive = false;
        request.Headers["Authorization"] = "Basic " + authInfo;
        string documento = "";
        MakeRequest(request,response=> documento = response,
                            (error) =>
                            {
                             if (errorAction != null)
                             {
                                errorAction(error);
                             }
                            }
                   );
        XMLResponse.LoadXml(documento);
        successAction(XMLResponse);
    }



    public void MakeJsonRequest<T>(string uri, Action<T> successAction, Action<Exception> errorAction)
    {
        string wufooAPIKey = "";
        string password = "";
        StringBuilder url = new StringBuilder();
        url.Append(uri);
        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url.ToString());
        string authInfo = wufooAPIKey + ":" + password;
        authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
        request.Timeout = 30000;
        request.KeepAlive = false;
        request.Headers["Authorization"] = "Basic " + authInfo;
       // request.Accept = "application/json";
      //  request.Method = "GET";
        MakeRequest(
           request,
           (response) =>
           {
               if (successAction != null)
               {
                   T toReturn;
                   try
                   {
                       toReturn = Deserialize<T>(response);
                   }
                   catch (Exception ex)
                   {
                       errorAction(ex);
                       return;
                   }
                   successAction(toReturn);
               }
           },
           (error) =>
           {
               if (errorAction != null)
               {
                   errorAction(error);
               }
           }
        );
    }
    private void MakeRequest(HttpWebRequest request, Action<string> successAction, Action<Exception> errorAction)
    {
        try{
            using (var webResponse = (HttpWebResponse)request.GetResponse())
            {
                using (var reader = new StreamReader(webResponse.GetResponseStream()))
                {
                    var objText = reader.ReadToEnd();
                    successAction(objText);
                }
            }
        }catch(HttpException ex){
            errorAction(ex);
        }
    }
    private T Deserialize<T>(string responseBody)
    {
        try
        {
            var toReturns = JsonConvert.DeserializeObject<T>(responseBody);
             return toReturns;
        }
        catch (Exception ex)
        {
            string errores;
            errores = ex.Message;
        }
        var toReturn = JsonConvert.DeserializeObject<T>(responseBody);
        return toReturn;
    }
}
}
Jesus Cañedo
fuente
-1
static async Task<AccessToken> GetToken()
{
        string clientId = "XXX";
        string clientSecret = "YYY";
        string credentials = String.Format("{0}:{1}", clientId, clientSecret);

        using (var client = new HttpClient())
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials)));
            List<KeyValuePair<string, string>> requestData = new List<KeyValuePair<string, string>>();
            requestData.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
            FormUrlEncodedContent requestBody = new FormUrlEncodedContent(requestData);
            var request = await client.PostAsync("https://accounts.spotify.com/api/token", requestBody);
            var response = await request.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<AccessToken>(response);
        }
    }
saurabh seth
fuente
Bienvenido a stackoverflow. Además de la respuesta que ha proporcionado, considere proporcionar una breve explicación de por qué y cómo soluciona el problema.
jtate
-2

Esto puede ayudar a configurar el encabezado:

WebClient client = new WebClient();

string authInfo = this.credentials.UserName + ":" + this.credentials.Password;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
client.Headers["Authorization"] = "Basic " + authInfo;
Codehelp
fuente
99
Él está usando HttpClient, no WebClient.
Jean Hominal