Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

Getting AccessToken to attach http request in a delegatinghandler to use in IHttpClientFactory In blazor serverside interactive

$
0
0

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)


Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>