Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient not sending authorization Bearer token in .Net Core 3.1

I have an ASP.NET Core MVC application that calls an ASP.NET Core WebApi using HttpClient, but I have to send the authorization header, the problem is that my HttpClient won't send the authorization header.

I have a service for calling the webapi that has the following constructor:

        public ApiService(HttpClient httpClient, IHttpContextAccessor accessor)
        {
            string token = accessor.HttpContext.User.FindFirstValue("JWToken"); // gets user token
            httpClient.BaseAddress = new Uri(AppSettings.BaseUrlApi); //sets the base URL of the webapi
            httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
            httpClient.Timeout = TimeSpan.FromMinutes(1);
            httpClient.DefaultRequestHeaders.Authorization
                         = new AuthenticationHeaderValue("Bearer", token);

            _httpClient = httpClient; // assigns to a private property "private readonly HttpClient _httpClient;"
        }

Then, when I post data to the webapi, I use the following method:

        public async Task<User> PostAsync(string url, User user)
        {
            StringContent jsonContent = new StringContent(
                JsonConvert.SerializeObject(user, Formatting.Indented, _jsonSettings), // _jsonSettings is a JsonSerializerSettings object
                Encoding.UTF8,
                "application/json");

            using HttpResponseMessage httpResponse =
                await _httpClient.PostAsync(url, jsonContent);
            httpResponse.EnsureSuccessStatusCode();
            string responseString = await httpResponse.Content.ReadAsStringAsync();

            return JsonConvert.DeserializeObject<User>(responseString, _jsonSettings);
        }

For requests that do not require an Authorization header, it works pretty fine, but it doesn't send the Authorization header, I have tried instantiating a new HttClient, using HttpRequestMessage and then SendAsync, but it never works, I also tried using httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}"); but it doesn't work, also TryAddWithoutValidation, but doesn't work. The worst is, when I check my httpClient object, the authorization token is there:

enter image description here

But then I get a 401 message from my webapi, and when I check the request received in the webapi, the authorization header is empty, and my webapi works fine when it receives requests from ajax calls, or applications like insomnia and postman.

I can't figure out what I am missing.

EDIT:

In my webapi, the request that's arriving is: enter image description here

My authorization header is {}

Now, when I receive a request from insomnia, for example, I have the following headers:

enter image description here

like image 600
Alef Duarte Avatar asked Sep 16 '20 17:09

Alef Duarte


People also ask

How do I send a POST request with Bearer Token Authorization header C #/ net code?

POST JSON With Bearer Token Authorization Header [C#/. NET Code] To send a POST JSON request with a Bearer Token authorization header, you need to make an HTTP POST request, provide your Bearer Token with an Authorization: Bearer {token} HTTP header and give the JSON data in the body of the POST message.

How do I add Auth header to HttpClient?

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.

How do I pass Authorization Bearer Token?

Bearer tokens enable requests to authenticate using an access key, such as a JSON Web Token (JWT). The token is a text string, included in the request header. In the request Authorization tab, select Bearer Token from the Type dropdown list. In the Token field, enter your API key value.

Can I pass Bearer Token in URL?

Don't pass bearer tokens in page URLs: Bearer tokens SHOULD NOT be passed in page URLs (for example, as query string parameters). Instead, bearer tokens SHOULD be passed in HTTP message headers or message bodies for which confidentiality measures are taken.

Is it possible to read access token from httpcontext in core?

That’s all, Finally, we found it is very simple to read access token from HttpContext in .NET Core. Happy Coding!! Do you have any comments or ideas or any better suggestions to share?

What is the difference between authentication and authorization in ASP core?

Hello ASP .NET Core v3.1! Authentication and Authorization are two different things, but they also go hand in hand. Think of Authentication as letting someone into your home and Authorization as allowing your guests to do specific things once they’re inside (e.g. wear their shoes indoors, eat your food, etc).

How do I enable authentication in ASP NET Core?

Authentication in ASP .NET Core. The quickest way to add authentication to your ASP .NET Core app is to use one of the pre-built templates with one of the Authentication options. The examples below demonstrate both the CLI commands and Visual Studio UI. Here are the CLI Commands for MVC, Razor Pages and Blazor (Server), respectively:

Is it possible to use JWT authentication in NET Core?

Here I did use the same JWT Authentication in .NET Core technique to secure the method and then followed by another API to fetch the access token programmatically to pass it to other components as required. The below piece of code is from the same sample which we learned in


1 Answers

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.

like image 123
slorello Avatar answered Oct 17 '22 02:10

slorello