Setting Authorization Header of Httpclient

Set Authorization Header of HttpClient

I solved this by the following line of code.

client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("key", "=" + apiKey);

Is setting the Authorization header in HttpClient safe?

With the approach you have, once you've set the default request header on your static instance, it will remain set without you having to keep setting it. This means that if you have multiple requests coming into your server, you could end up in a situation where the header is set for one user and then changed by another request before that first request makes it out the door.

One option to avoid this would be to use SendAsync when using user-specific authorisation headers. This allows you to tie the header to a specific message, rather than setting it as a default for the HttpClient itself.

The code is a bit more verbose, but would look something like this:

using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, "http://path/to/wherever"))
{
httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "TheToken");

using (var httpResponseMessage = httpClient.SendAsync(httpRequestMessage))
{
// ...
}
}

As you can see, the header is set specially on each request and therefore the issue of mixing up the headers goes away. The obvious downside is that this syntax is more verbose.

HttpClient and setting Authorization headers

A quick look over their documentation seems to indicate that the projects.json endpoint accepts the following in the body of the POST:

{
"name": "This is my new project!",
"description": "It's going to run real smooth"
}

You're sending the User-Agent as the POST body. I'd suggest you change your code as follows:

    var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", "[USERNAME]", "[PASSWORD]")));
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Add("User-Agent", "MyApp [EMAIL ADDRESS]");
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
var response = await httpClient.PostAsJsonAsync(
"https://basecamp.com/[USER ID]/api/v1/projects.json",
new {
name = "My Project",
description = "My Project Description"
});

var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseContent);
}

This posts the payload as specified in the docs and sets your user agent in the headers as it should be.

How do I set Authorization Header for my HttpClient across all pages?

The best approach depends a lot on your implementation details. What happens if the API key isn't available or becomes invalid? Are you managing a single API key for any calls to the client, or are you managing multiple API keys for different scopes or multiple users?

One approach would be to build a Typed Client using HttpClientFactory; a typed client allows you to essentially write a custom class for which an HttpClient instance is injected and managed by the factory, and for which you can write specific behaviors that your client needs, such as handling API key checking and storage through dependency injection. You might write an interface/implementation called IAuthenticatedClient / AuthenticatedClient that exposes methods such as UpdateKey() and SendAuthenticatedAsync() where these methods sit on top of a persistent store such as an in-memory cache or database that retains the API key and applies it to calls before they're sent through the HttpClient, then register it with services.AddHttpClient<IAuthenticatedClient, AuthenticatedClient>(); and inject it where you need it.

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-6.0#typed-clients

You might also consider implementing cross-cutting concerns such as API key application through the use of a delegating handler attached to a named or typed client, which is one of the cases described by Microsoft's documentation. Multiple handlers can be attached to create a middleware pipeline for outbound requests and responses sent through HttpClients to handle things like headers, logging, error handling, key management, etc.

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-6.0#outgoing-request-middleware

HttpClient not sending authorization Bearer token in .Net Core 3.1

The code you are using looks as though it should work, I tried something similar on my end and it added the JWT as expected. Is it possible that the 401 is legitimately referring to a bad token? I'd try decoding it with: https://jwt.io/ and validate that all the claims in it make sense (e.g. expiration) and that it is signed correctly.

UPDATE

Adding some code that's very similar to what you are trying to do that does work for me, FYI this is making a phone call via an API, leaving the JWT generation and command generation out for simplicity

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");

var json = JsonConvert.SerializeObject(command,
Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore });
httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", jwt);

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

var response = httpClient.PostAsync("https://api.nexmo.com/v1/calls", content).Result;

I can confirm that this most certainly adds the JWT as a bearer token into the header (it would not work otherwise)

hopefully this helps.

Angular HttpClient not setting Authorization header

The issue is not with Angular. Modern browsers send a preflight OPTIONS request for most cross-domain requests, which is not supported by Mailchimp. The Mailchimp API does not support client-side implementations:

MailChimp does not support client-side implementation of our API using
CORS requests due to the potential security risk of exposing account
API keys.

It would have been nice if this was stated a bit more obviously, but I didn't notice it at first. The best solution is to use jsonp.

.NET core set auth header for HttpClient service instance

You can add the authHeader after the client was created

Add the http client as you doing right now:

services.AddHttpClient<IExternalService, ExternalService>(); 

And you have your service class with a method to authenticate and inject the header into the client:

public class myService 
{
private readonly HttpClient _client

public myService(HttpClient client)
{
_client = client;
}

private Task Authenticate()
{
... your authentication logic here
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_client.DefaultRequestHeaders.Add("Auth", yourToken);
}

public MyMethod()
{
try
{
_client.get....
}
catch()
{
catch the unauthorized exception here and call Authenticate()
}
}
}

Then, in all api calls, put an catch block to catch 401, 403 errors and call the authenticate method again before you re-do the api call.

*For the last part i think you can look at the Polly package to automatizate this process.

As well you can just check the response status code instead of catching an exception:

public class myService 
{
private readonly HttpClient _client

public myService(HttpClient client)
{
_client = client;
}

private Task Authenticate()
{
... your authentication logic here
_client.DefaultRequestHeaders.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
_client.DefaultRequestHeaders.Add("Auth", yourToken);
}

public MyMethod()
{
try
{
var retry = false;
do
{
var response = _client.get....
if (!response.IsSuccessStatusCode)
{
if(response.StatusCode == HttpStatusCode.401 || response.StatusCode == HttpStatusCode.403)
{
Authenticate();
retry = true;
}
}
}
catch()
{
}
}
while (retry);
}
}

HttpClient Authorization Header not being send when set BrowserRequestMode to NoCors

from msdn web docs :

no-cors — Prevents the method from being anything other than HEAD, GET
or POST, and the headers from being anything other than simple
headers.

Simple headers are what we call CORS-safelisted request headers like :

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type

Authorization header is not being sent because in your second line you're preventing that header from being sent by enabling cors.
I don't know if you're doing that for some purpose or not but I think it's a cors related thing , your code is correct. There are plenty of answers explaining CORS out there.



Related Topics



Leave a reply



Submit