Im trying to write a blazor app in dotnet 8 that only uses server side interactive rendering. I want to authenticate against Azure tenant. I have the login working correctly, Im just having a hard time figuring out how to attach the correct authorization token to an http client that is making requests to a different dotnet api that is also authenticated against tenant. It understand that the scope that delegating handlers use is different than that of the signalR circuit that is instantiaded when a client accesses the site. I found this article https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/dependency-injection?view=aspnetcore-9.0#access-server-side-blazor-services-from-a-different-di-scope that describes how to get the authentication state from the circuit. Im just having a hard time figuring out how to ge the access token from this.
using LogisticsTruckScales.BlazorServer.Components;using LogisticsTruckScales.BlazorServer.Services.Secuirty;using Microsoft.AspNetCore.Authentication.OpenIdConnect;using Microsoft.AspNetCore.Authorization;using Microsoft.AspNetCore.Components.Authorization;using Microsoft.AspNetCore.Components.Server.Circuits;using Microsoft.Identity.Web;using MudBlazor.Services;using System.Security.Claims;var builder = WebApplication.CreateBuilder(args);builder.Services.AddMudServices();builder.Services.AddScoped<CircuitServicesAccessor>();builder.Services.AddScoped<CircuitHandler, ServicesAccessorCircuitHandler>();// Add services to the containerbuilder.Services.AddRazorComponents() .AddInteractiveServerComponents();builder.Services.AddScoped<ScaleTransactionManagerAuthorizationHandler>();builder.Services.AddHttpClient("ScaleTransactionManager", client =>{ client.BaseAddress = new Uri(builder.Configuration["ScaleTransactionManager:BaseUrl"]);}).AddHttpMessageHandler<ScaleTransactionManagerAuthorizationHandler>();builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi() .AddInMemoryTokenCaches();builder.Services.AddAuthorization(options =>{ options.FallbackPolicy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build();});var app = builder.Build();app.UseAuthentication();app.UseAuthorization();app.UseAntiforgery();app.MapRazorComponents<App>().AddInteractiveServerRenderMode();app.Run();using Microsoft.AspNetCore.Components.Authorization;using Microsoft.Identity.Client;using Microsoft.Identity.Web;using System.Net.Http.Headers;using System.Security.Claims;using static System.Formats.Asn1.AsnWriter;namespace LogisticsTruckScales.BlazorServer.Services.Secuirty{ public class ScaleTransactionManagerAuthorizationHandler : DelegatingHandler { private readonly CircuitServicesAccessor circuitServicesAccessor; private readonly IConfiguration _configuration; public ScaleTransactionManagerAuthorizationHandler(CircuitServicesAccessor circuitServicesAccessor, IConfiguration configuration) { this.circuitServicesAccessor = circuitServicesAccessor; _configuration = configuration; } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var authStateProvider = circuitServicesAccessor.Services .GetRequiredService<AuthenticationStateProvider>(); var authState = await authStateProvider.GetAuthenticationStateAsync(); //I have the auth state here. I want to pass the access token to the request. // Attach the token to the request request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); return await base.SendAsync(request, cancellationToken); } }}using Microsoft.AspNetCore.Components.Server.Circuits;namespace LogisticsTruckScales.BlazorServer.Services.Secuirty{ public class CircuitServicesAccessor { static readonly AsyncLocal<IServiceProvider> blazorServices = new(); public IServiceProvider? Services { get => blazorServices.Value; set => blazorServices.Value = value; } } public class ServicesAccessorCircuitHandler( IServiceProvider services, CircuitServicesAccessor servicesAccessor) : CircuitHandler { public override Func<CircuitInboundActivityContext, Task> CreateInboundActivityHandler( Func<CircuitInboundActivityContext, Task> next) => async context => { servicesAccessor.Services = services; await next(context); servicesAccessor.Services = null; }; } public static class CircuitServicesServiceCollectionExtensions { public static IServiceCollection AddCircuitServicesAccessor( this IServiceCollection services) { services.AddScoped<CircuitServicesAccessor>(); services.AddScoped<CircuitHandler, ServicesAccessorCircuitHandler>(); return services; } }}I know I cant use ITokenAquistion directly in my handler, Ive tried this and I get (MsalUiRequiredException: No account or login hint was passed to the AcquireTokenSilent call)