Impostazione dell'intestazione di autorizzazione di HttpClient


483

Ho un HttpClient che sto usando per un'API REST. Tuttavia, ho problemi a configurare l'intestazione dell'autorizzazione. Devo impostare l'intestazione sul token che ho ricevuto dall'esecuzione della mia richiesta OAuth. Ho visto del codice per .NET che suggerisce quanto segue,

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

Tuttavia, la classe Credential non esiste in WinRT. Qualcuno ha qualche idea su come impostare l'intestazione dell'autorizzazione?


1
A quale spazio dei nomi appartiene la classe Credential?
Kampsj,

@kampsj Non lo so poiché è uno spazio dei nomi .NET che non esiste in WinRT
Stephen Hynes

1
Perché non request.Headers.Add ("Autorizzazione", token);
ahll

Risposte:


817

Quindi il modo per farlo è il seguente,

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

16
come ottieni "Il tuo token Oauth"?
Secret Squirrel,

3
Quello che ho usato è: client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "encrypted user/pwd");prendere utente / pwd crittografato dall'estensione chrome Advanced Rest Client.
Rosso

6
@Red fyi, il secondo parametro è l'utente con codifica base64: password (non crittografata).
n00b

5
La mia applicazione lo utilizzava felicemente da anni, poi all'improvviso ho iniziato a ottenere un RuntimeBinderException. Ho dovuto passare a httpClient.DefaultRequestHeaders.Add ("Autorizzazione", "Portatore", "Il tuo token Oauth"); per farlo ripartire.
Kraeg

8
@kraeg, il codice che hai elencato non viene compilato, intendevi concatenare le ultime 2 stringhe in questo modo: 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}")));

27
@MickyDuncan HttpClient ha DefaultRequestHeaders.Authorization. E questa risposta mi ha appena salvato la giornata. Mille grazie a WhiteRabbit.
Joey Schluchter,

3
Questo non funziona, se si controlla l'intestazione Auhtorization non contiene altro che una stringa Basic.
Raffaeu,

1
Qualcuno può spiegare perché è importante convertire il nome utente e la password in una stringa base64? Non offre alcuna crittografia reale, quindi perché è importante?
Jonathan Wood,

3
@JonathanWood Perché quello; s come è definito per essere utilizzato. Basic non offre alcuna crittografia, ma solo una codifica sufficiente per evitare problemi con la scelta dei caratteri della password in un'intestazione.
Richard,

4
C'è qualche motivo particolare per cui hai usato la codifica ASCII qui? Suppongo che non ci siano problemi con l'utilizzo della codifica UTF8 poiché lo stiamo codificando Base64 comunque. Immagino che mi chiedo se la specifica di autenticazione di base dice che il combo username: password dovrebbe essere solo in ASCII?
schiaccia il

82

Cerco un buon modo per affrontare questo problema e sto esaminando la stessa domanda. Spero che questa risposta possa aiutare chiunque abbia lo stesso problema a cui piaccio.

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

riferimento da https://www.theidentityhub.com/hub/Documentation/CallTheIdentityHubApi


1
Sto facendo esattamente la stessa cosa @willie e sto ancora ricevendo un 401 dalla mia API
SomethingOn

2
Ciao @SomethingOn Penso che non hai ottenuto una chiave token corretta, quindi hai ottenuto 401, condividerò la mia strada sul mio personale "Fai una domanda", speriamo che possa aiutarti a risolvere il tuo problema.
Willie Cheng,

14
Non dovresti mettere un HttpClient in un usingblocco. (Sì, lo so che suona all'indietro, ma usingperderai le connessioni se utilizzi invece di riciclare semplicemente HttpClient.)
Jonathan Allen

42

Poiché è una buona pratica riutilizzare l'istanza di HttpClient , per problemi di prestazioni e esaurimento delle porte , e poiché nessuna delle risposte fornisce questa soluzione (e addirittura ti conduce verso cattive pratiche :(), ho messo qui un link verso la risposta che ho fatto su una domanda simile:

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

Alcune fonti su come usare HttpClient nel modo giusto:


5
Il problema dell'esaurimento del porto non è uno scherzo. Non succede quasi mai nel QA, ma colpirà qualsiasi progetto pesantemente utilizzato nella produzione.
Jonathan Allen,

Vedi il mio post per un esempio concreto stackoverflow.com/a/59052193/790635
emp

41

Sono d'accordo con la risposta di TheWhiteRabbit ma se hai molte chiamate usando HttpClient il codice mi sembra un po 'ripetitivo secondo me.

Penso che ci siano 2 modi per migliorare un po 'la risposta.

Creare una classe di supporto per creare il client:

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 metodo di estensione:

Non vince un premio di bellezza ma funziona alla grande :)

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

Ancora una volta penso che 2 sopra le opzioni rendano il client che usa statement un po 'meno ripetitivo. Tieni presente che è consigliabile riutilizzare HttpClient se stai effettuando più chiamate http, ma penso che sia un po 'fuori portata per questa domanda.


20
vedo che la tua risposta è stata annullata ma non consiglierei questo approccio TL; DR è chiaramente sbagliato a causa dell'esaurimento del socket, ecco il link di
lacripta

2
@lacripta, questo è vero ma se leggi le ultime 2 frasi dico la sua migliore pratica per riutilizzare HttpClient esattamente per questo motivo, ma penso che sia fuori portata per questa domanda.
Florian Schaal,

1
posso vedere il tuo punto ma stai suggerendo che il codice è ripetitivo, questo potrebbe portare ad un uso improprio di questo metodo di fabbrica, sarebbe bene indicare nelle prime righe che causerà problemi di utilizzo delle risorse in futuro specialmente per questo caso. e non solo un avvertimento che la maggior parte non leggerà.
lacripta,

1
L'uso di HttpClientFactory sarebbe molto meglio per evitare il problema di esaurimento del socket.
RyanOC,

21

Stavo impostando il gettone al portatore

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

Funzionava in un endpoint, ma non in un altro. Il problema era che avevo minuscole bsu "bearer". Dopo il cambiamento ora funziona per entrambe le API che sto colpendo. Una cosa così facile da perdere se non la stai nemmeno considerando come uno dei covoni di fieno per cercare l'ago.

Assicurati di avere "Bearer"- con il capitale.


18

Ti consiglio:

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

E poi puoi usarlo così:

var response = await client.GetAsync(url);
if (response.IsSuccessStatusCode)
{
    responseMessage = await response.Content.ReadAsAsync<ResponseMessage>();
}

Ad esempio, se il token scade ogni 1h, è necessario aggiornare HttpClient con questa soluzione. Suggerirei di verificare che il token sia ancora valido e di aggiornarlo in altro modo e di aggiungerlo al messaggio HttpRequest
Johan Franzén,

13

Per impostare l'autenticazione di base con C # HttpClient. Il seguente codice funziona per me.

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

Esattamente quello di cui avevo bisogno, grazie.
rchrd

10

Ecco come l'ho fatto:

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", "sa@role.com"},
           {"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());
      }
   }
}

Questo video di YouTube mi aiuta molto. Per favore controlla. https://www.youtube.com/watch?v=qCwnU06NV5Q


9

Utilizzare l'autorizzazione di base e i parametri 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();
                    }

2
Non includere codice per disabilitare il controllo dei certificati SSL in un esempio come questo. Le persone possono copiare alla cieca il tuo codice senza rendersi conto di ciò che fa. Ho rimosso quelle righe per te.
Giovanni

9

Se si desidera riutilizzare il HttpClient, si consiglia di non utilizzare il DefaultRequestHeaderscome vengono utilizzati per inviare con ogni richiesta.

Puoi provare questo:

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

8

6 anni dopo, ma aggiungendolo nel caso aiuti qualcuno.

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

Ha funzionato per me. Al contrario della risposta di Willie Cheng che non ha funzionato per me.
user890332

5

Opzione UTF8

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

3

Utilizzando la AuthenticationHeaderValueclasse di System.Net.Httpassemblaggio

public AuthenticationHeaderValue(
    string scheme,
    string parameter
)

possiamo impostare o aggiornare l' Authorizationintestazione esistente per il nostro httpclientlike così:

httpclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TokenResponse.AccessToken);

1
Benvenuto su SO, ma per favore aggiungi un po 'più di contesto.
JP Hellemons,

La risposta è esatta ma non sarebbe male avere un solo liner che spieghi cosa dovrebbe fare il suo codice. Sto solo dicendo.
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}";
    }
}

1

Nel caso in cui si desideri inviare una HttpClientrichiesta con Bearer Token, questo codice può essere una buona soluzione:

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

0

In net .core puoi usare

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

o

var client = new HttpClient();
client.SetBearerToken(token);

1
Il primo esempio non funziona in quanto SetBasicAuthentication()non è disponibile per impostazione predefinita, quindi deve essere un metodo di estensione. Dove è definito?
ViRuSTriNiTy

0

Potrebbe essere più semplice utilizzare una libreria esistente.

Ad esempio, i seguenti metodi di estensione vengono aggiunti 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);

0

Il flusso di processo Oauth è complesso e c'è sempre spazio per un errore o un altro. Il mio suggerimento sarà di utilizzare sempre il codice boilerplate e un set di librerie per il flusso di autenticazione OAuth, semplificandoti la vita.

Ecco il link per il set di librerie. Librerie OAuth per .Net


-1

questo potrebbe funzionare, se stai ricevendo un json o un xml dal servizio e penso che questo possa darti un'idea di come funzionano anche le intestazioni e il tipo T, se usi la funzione MakeXmlRequest (inserisci i risultati in xmldocumnet) e MakeJsonRequest (metti il ​​json nella classe che desideri che abbia la stessa struttura della risposta json) nel prossimo modo

/*-------------------------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;
    }
}
}

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

Benvenuto in StackOverflow. Oltre alla risposta fornita, ti consigliamo di fornire una breve spiegazione del perché e di come risolvere il problema.
jtate,

-2

Questo può aiutare a impostare l'intestazione:

WebClient client = new WebClient();

string authInfo = this.credentials.UserName + ":" + this.credentials.Password;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
client.Headers["Authorization"] = "Basic " + authInfo;

9
Sta usando HttpClient, no WebClient.
Jean Hominal,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.