Definindo o cabeçalho de autorização do HttpClient

483

Eu tenho um HttpClient que estou usando para uma API REST. No entanto, estou com problemas para configurar o cabeçalho da autorização. Preciso definir o cabeçalho para o token que recebi ao fazer minha solicitação OAuth. Eu vi algum código para .NET que sugere o seguinte,

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

No entanto, a classe Credential não existe no WinRT. Alguém tem alguma idéia de como definir o cabeçalho de autorização?

Stephen Hynes
fonte
1
A que namespace a classe Credential pertence?
kampsj
@kampsj Eu não sei já que é um namespace .NET que não existe no WinRT
Stephen Hynes
1
Por que não request.Headers.Add ("Authorization", token);
precisa saber é

Respostas:

817

Portanto, a maneira de fazer isso é a seguinte,

httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", "Your Oauth token");
Stephen Hynes
fonte
16
como você recebe "Seu token Oauth"?
Secret Squirrel
3
O que eu usei é: client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "encrypted user/pwd");Tirar usuário / senha criptografado da extensão de cromo do Advanced Rest Client.
Vermelho
6
@ Red fyi, o segundo parâmetro é o usuário codificado em base64: senha (não é criptografada).
N00b
5
Meu aplicativo estava felizmente usando isso há muito tempo; então, do nada, comecei a receber uma RuntimeBinderException. Eu tive que mudar para httpClient.DefaultRequestHeaders.Add ("Authorization", "Bearer", "Your Oauth token"); para voltar a funcionar.
kraeg
8
@kraeg, o código que você listou não é compilado, você quis concatenar as duas últimas strings assim: client.DefaultRequestHeaders.Add ("Authorization", "Bearer" + "Your Oauth token");
TroySteven
354
request.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue(
        "Basic", Convert.ToBase64String(
            System.Text.ASCIIEncoding.ASCII.GetBytes(
               $"{yourusername}:{yourpwd}")));
TheWhiteRabbit
fonte
27
@MickyDuncan HttpClient tem um DefaultRequestHeaders.Authorization. E essa resposta acabou de salvar meu dia. Muito obrigado a WhiteRabbit.
Joey Schluchter
3
Isso não está funcionando, se você inspecionar o cabeçalho Auhtorization, não conterá nada além de uma string Basic.
Raffaeu
1
Alguém pode explicar por que é importante converter o nome de usuário e a senha em uma string base64? Ele não oferece criptografia real, então por que isso importa?
Jonathan Madeira
3
@ JonathanWood Porque é assim que é definido para ser usado. O Basic não oferece criptografia, apenas codificação suficiente para evitar problemas com a escolha dos caracteres da senha em um cabeçalho.
Richard
4
Existe algum motivo específico para você usar a codificação ASCII aqui? Eu suponho que não há problema em usar a codificação UTF8, pois estamos codificando a Base64 de qualquer maneira. Acho que estou me perguntando se a especificação de autenticação básica diz que a combinação de nome de usuário: senha deve estar apenas em ASCII?
esmagar
82

Eu procuro uma boa maneira de lidar com esse problema e estou analisando a mesma pergunta. Felizmente, esta resposta ajudará todos que têm o mesmo problema a gostar de mim.

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.
    ....
}

referência de https://www.theidentityhub.com/hub/Documentation/CallTheIdentityHubApi

Willie Cheng
fonte
1
Eu estou fazendo exatamente a mesma coisa @willie e ainda estou recebendo um 401 da minha API
SomethingOn
2
Oi, @AlgoEm que eu acho que você não recebeu uma chave de token correta, para que você tenha 401, vou compartilhar meu caminho na minha "Pergunta pessoal", espero que possa ajudá-lo a lidar com o seu problema.PS aguardando um momento
Willie Cheng
14
Você não deve colocar um HttpClient em um usingbloco. (Sim, eu sei que isso soa ao contrário, mas você vazará conexões se usar em usingvez de apenas reciclar o HttpClient.) #
Jonathan Allen
42

Como é uma boa prática reutilizar a instância HttpClient , para problemas de desempenho e esgotamento de portas , e porque nenhuma das respostas fornece essa solução (e até mesmo leva você a práticas inadequadas :(), coloquei aqui um link para a resposta que fiz em uma pergunta semelhante:

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

Algumas fontes sobre como usar o HttpClient da maneira certa:

Philippe
fonte
5
O problema da exaustão da porta não é brincadeira. Quase nunca acontece no controle de qualidade, mas atingirá qualquer projeto muito usado na produção.
Jonathan Allen
Veja meu post para um exemplo concreto stackoverflow.com/a/59052193/790635
emp
41

Concordo com a resposta do TheWhiteRabbit, mas se você tiver muitas chamadas usando o HttpClient, o código parecerá um pouco repetitivo na minha opinião.

Eu acho que existem 2 maneiras de melhorar um pouco a resposta.

Crie uma classe auxiliar para criar o 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
}

Crie um método de extensão:

Não ganha um prêmio de beleza, mas funciona muito bem :)

    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); 
}

Novamente, acho que as duas opções acima tornam o cliente usando a declaração um pouco menos repetitivo. Lembre-se de que é uma boa prática reutilizar o HttpClient se você estiver fazendo várias chamadas http, mas acho que está um pouco fora do escopo desta pergunta.

Florian Schaal
fonte
20
eu posso ver a sua resposta é upvoted, mas eu não recomendo essa abordagem TL; DR é errado planície porque tomada exaustão, aqui é a explicação ligação
lacripta
2
@acracta, isso é verdade, mas se você ler as duas últimas frases, digo que é uma boa prática reutilizar o HttpClient exatamente por esse motivo, mas acho que está fora do escopo dessa pergunta.
Florian Schaal
1
Eu posso entender o seu ponto, mas você está fazendo uma sugestão dizendo que o código é repetitivo, isso pode levar ao uso indevido desse método de fábrica; seria bom apontar nas primeiras linhas que causará problemas no uso de recursos no futuro, especialmente para este caso. e não apenas um aviso que a maioria não lê.
lacripta
1
Usar o HttpClientFactory seria muito melhor para evitar o problema de exaustão do soquete.
RyanOC
21

Eu estava configurando o token do portador

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

Ele estava trabalhando em um terminal, mas não em outro. A questão era que eu estava bem minúsculas "bearer". Depois da mudança, agora funciona para as duas APIs que estou acertando. É uma coisa tão fácil de perder, se você não está nem considerando isso como um dos palheiros para procurar a agulha.

Certifique-se de ter "Bearer"- com capital.

Alan Ball
fonte
18

Eu sugiro a você:

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

E então você pode usá-lo assim:

var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
    responseMessage = await response.Content.ReadAsAsync<ResponseMessage>();
}
Amankhani MohammadJavad
fonte
Se o seu token atingir o tempo limite a cada 1 h, por exemplo, você precisará atualizar o HttpClient com esta solução. Sugiro verificar se seu token ainda é válido e atualizá-lo e adicioná-lo ao HttpRequestMessage
Johan Franzén
13

Para definir a autenticação básica com o C # HttpClient. O código a seguir está funcionando para mim.

   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
fonte
Exatamente o que eu precisava, obrigado.
rchrd 15/01
9

Isto é como eu fiz isso:

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 vídeo do YouTube me ajuda muito. Por favor, confira. https://www.youtube.com/watch?v=qCwnU06NV5Q

Dayan
fonte
9

Use autorização básica e parâmetros 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
fonte
2
Você não deve incluir código para desativar a verificação de certificados SSL em um exemplo como este. As pessoas podem copiar cegamente seu código sem perceber o que ele faz. Eu removi essas linhas para você.
João
9

Se você deseja reutilizar o HttpClient, é recomendável não usá-lo DefaultRequestHeaderscomo eles são usados ​​para enviar com cada solicitação.

Você pode tentar o seguinte:

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
fonte
8

Seis anos depois, mas adicionando isso no caso de ajudar alguém.

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
fonte
Trabalhou para mim. Ao contrário da resposta de Willie Cheng, que não funcionou para mim.
user890332
5

Opção UTF8

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

Usando AuthenticationHeaderValueclasse de System.Net.Httpmontagem

public AuthenticationHeaderValue(
    string scheme,
    string parameter
)

podemos definir ou atualizar o Authorizationcabeçalho existente para o seguinte httpclient:

httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TokenResponse.AccessToken);
Fusão
fonte
1
Bem-vindo ao SO, mas adicione um pouco mais de contexto.
JP Hellemons
A resposta é imediata, mas não faria mal ter uma fila explicando o que seu código deveria fazer. Apenas dizendo.
22717 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
fonte
1

Caso você queira enviar uma HttpClientsolicitação com o Bearer Token, esse código pode ser uma boa solução:

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
fonte
0

No net .core você pode usar

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

ou

var client = new HttpClient();
client.SetBearerToken(token);
Thom Kiesewetter
fonte
1
O primeiro exemplo não funciona, pois SetBasicAuthentication()não está disponível por padrão, portanto deve ser um método de extensão. Onde é definido?
ViRuSTriNiTy
0

Pode ser mais fácil usar uma biblioteca existente.

Por exemplo, os métodos de extensão abaixo são adicionados ao 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
fonte
0

O fluxo do processo Oauth é complexo e sempre há espaço para um erro ou outro. Minha sugestão será sempre usar o código padrão e um conjunto de bibliotecas para o fluxo de autenticação OAuth. Isso facilitará sua vida.

Aqui está o link para o conjunto de bibliotecas. Bibliotecas OAuth para .Net

Khurram Jamil
fonte
-1

isso poderia funcionar, se você estiver recebendo um json ou um xml do serviço e acho que isso pode lhe dar uma idéia sobre como os cabeçalhos e o tipo T também funcionam, se você usar a função MakeXmlRequest (colocar resultados em xmldocumnet) e MakeJsonRequest (coloque o json na classe que você deseja que tenha a mesma estrutura que a resposta do json) da próxima maneira

/*-------------------------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
fonte
-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
fonte
Bem-vindo ao stackoverflow. Além da resposta que você forneceu, considere fornecer uma breve explicação de por que e como isso resolve o problema.
Jtate 19/11
-2

Isso pode ajudar a definir o cabeçalho:

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
fonte
9
Ele está usando HttpClient, não WebClient.
Jean hominal