Azure Signal R Service HttpContext Null

96 views Asked by At

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>();
0

There are 0 answers