I have a .NET 6 Blazor Server app that communicates with our .NET 6 Web Api. Before we call the api we get a token for authorization and log the userId. This is done within a DelegatingHandler before we send the http request to the API. This has worked fine, but we recently changed our code to use the Azure Signal R service. Since then the code falls over at the httcontext line, it seems any line that references httpcontext is now an issue. I have added the httpcontextaccessor in startup and also injecting it into the service. I've also made sure the line in startup for registering httpcontext is before signal r incase that was the issue
Any ideas why this is happening. Below is the line of code as an example where its falling over.
public class AuthenticationDelegatingHandler : DelegatingHandler
{
private readonly ITokenAcquisition _tokenAcquisition;
private readonly IConfiguration _configuration;
private readonly ILogger<AuthenticationDelegatingHandler> _logger;
private readonly IHttpContextAccessor _httpContext;
public AuthenticationDelegatingHandler(ITokenAcquisition tokenAcquisition, IConfiguration configuration, ILogger<AuthenticationDelegatingHandler> logger, IHttpContextAccessor httpContext)
{
_tokenAcquisition = tokenAcquisition;
_configuration = configuration;
_logger = logger;
_httpContext = httpContext;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var scopes = new[] { _configuration["ApiScope"] };
string accessToken = string.Empty;
var userObject = _httpContext?.HttpContext?.User?.Claims.SingleOrDefault(_ => _.Type == ClaimTypes.NameIdentifier)?.Value;
try
{
accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(scopes!);
_logger.LogInformation("Successfully retrieved access token from Azure for communication with API. User ObjectId - {UserObject}", userObject);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error while fetching access token for communication with API. Details: {Message}. {InnerException}", ex.Message, ex.InnerException);
throw;
}
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var response = await base.SendAsync(request, cancellationToken);
return response;
}
}
Below is my code where I register my handler during startup:
builder.Services.AddRazorPages();
builder.Services.AddHttpContextAccessor();
builder.Services.AddServerSideBlazor()
.AddMicrosoftIdentityConsentHandler();
builder.Services.AddScoped<NotificationService>();
builder.Services.AddTransient<AuthenticationDelegatingHandler>();
builder.Services.AddHttpClient("WebAPI", client => client.BaseAddress = new Uri(builder.Configuration["ApiBaseAddress"] ?? string.Empty))
.AddHttpMessageHandler<AuthenticationDelegatingHandler>();