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