oauth-2.0jwtidentityserver4

Bearer token not set as expected


In my Asp.Net Core Web App, I use IdentityModel.AspNetCore to handle setting the bearer token on all requests to my API, but I doesn't seem to work as expected.

The access_token is retrived by IdentityServer, and it works great if I set it manually

public async Task OnGetAsync()
{
    var httpClient = _httpClientFactory.CreateClient("RemoteApi");
    var request = new HttpRequestMessage(HttpMethod.Get, "api/WeatherForecast");
    
    //this should not be necessary..!!!
    var accessToken = await HttpContext.GetTokenAsync("access_token");
    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

    var response = httpClient.Send(request, HttpCompletionOption.ResponseHeadersRead);

    response.EnsureSuccessStatusCode();

    var content = response.Content.ReadAsStringAsync().Result;

    if (content != null)
    {
        WeatherForecasts = JsonSerializer.Deserialize<List<WeatherForecast>>(content, _jsonOptions);
    }
}

In the Web App configuration I add the following

builder.Services.AddAccessTokenManagement();
builder.Services.AddHttpClient("RemoteApi", client =>
 {
  client.BaseAddress = new Uri(builder.Configuration["RemoteApiRoot"]);
  client.DefaultRequestHeaders.Clear();
  client.DefaultRequestHeaders.Add("Accept", "application/json");
 }).AddUserAccessTokenHandler();

As far as I understand, that is all the setup required. If I don't manually add the access_token as a bearer token when I create the httpClient in my Razor Page, then I get Unauthorized from the API.

The API is configured with bearer

JsonWebTokenHandler.DefaultInboundClaimTypeMap.Clear();

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = builder.Configuration["OpenId:Authority"];
        options.Audience = "remoteapi";
    });

Solution

  • This issue boiled down to synchronous vs. asynchronous behavior.

    Using synchronous is probably blocking the service to set the token.

    var response = httpClient.Send(request, HttpCompletionOption.ResponseHeadersRead);
    

    Switching to asynchronous solved it, and it then works as expected.

    var response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);