Home > Back-end >  No service for type ' Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAut
No service for type ' Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAut

Time:08-07

I am currently working on a project that consists of sub-projects such as WebApp, API, and Client class library. (The project structure is shown below). Project Solution Structure

Although the project is a web-based project, it uses windows Identity as authentication identity since it is an internal application. I implemented the authorization policy of the WebApp project without any problems by following the steps in the implementation_link. Now I can control access using DataAnnotation in WebApp (ex. [Authorize(Roles = "Admin"]). If I add Authorization control on the API side, WebApp cannot access this API. This is because of HttpContext.User is null. I found the solution to this problem solution_link. I adapted this solution to the project as below:

ServiceCollectionExtensions.cs in WebApp project:

public static IServiceCollection AddAuraServices(this IServiceCollection serviceCollection, IConfiguration configuration)
    {
        serviceCollection.AddTransient<IModelDatabaseNamesProvider, StandardCasingModelDatabasesNamesProvider>();
        serviceCollection.Configure<RouteOptions>(routeOptions =>
        {
            routeOptions.ConstraintMap.Add(ModelDatabasesNameConstraint.Name, typeof(ModelDatabasesNameConstraint));
        });
        serviceCollection.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        serviceCollection.AddScoped<IModelMetadataProvider>(serviceProvider =>
        {
            var httpContext = serviceProvider.GetRequiredService<IHttpContextAccessor>().HttpContext;
            var modelName = httpContext.Request.RouteValues["model-name"].ToString();
            return new ModelMetadataProvider(modelName);
        });

        DateOnlyTypeConverter.AddAttributeToType();

        serviceCollection.AddHttpClient<UploadRulesClient>("ServerAPI", (httpClient) =>
        {
            httpClient.BaseAddress = new Uri(configuration["AuraApiClient:BaseAddress"]);
        }).AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

        serviceCollection.AddHttpClient<ScenarioZipFilesClient>("ServerAPI",(httpClient) =>
        {
            httpClient.BaseAddress = new Uri(configuration["AuraApiClient:BaseAddress"]);
        }).AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();

        serviceCollection.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
            .CreateClient("ServerAPI"));


        var jsonSerializerOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        };

        ClientJsonResponse.Configure(jsonSerializerOptions);
        serviceCollection.AddSingleton(jsonSerializerOptions);
        serviceCollection.AddAuraDropzoneConfig(configuration);
        return serviceCollection;
    }

Startup.cs of WebApp:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {

        services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
        services.AddAuthorization();

        services.AddControllersWithViews();
        //services.AddRazorPages();
        services.AddAuraServices(Configuration);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        //app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(name: "model-database", pattern: "{model-name:modeldatabasename}/{controller=ZipFiles}/{action=Index}/{id?}");
            endpoints.MapControllerRoute(name: "default", pattern: "", new { controller = "Home", action = "Index" });
            //endpoints.MapRazorPages();
        });
    }
}

But this time I am getting No service for Type Error. How can I solve this problem? Where do you think I am going wrong? Thanks

CodePudding user response:

You have to register BaseAddressAuthorizationMessageHandler:

serviceCollection.AddTransient<BaseAddressAuthorizationMessageHandler>();

CodePudding user response:

Thank you for your comment but it didn't work. I tried this code line into either ServiceCollectionExtension.cs file and Startup.cs but the result is the same. I got this error:

System.AggregateException HResult=0x80131500 Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAuthorizationMessageHandler Lifetime: Transient ImplementationType: Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAuthorizationMessageHandler': Unable to resolve service for type 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.IAccessTokenProvider' while attempting to activate 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAuthorizationMessageHandler'.) Source=Microsoft.Extensions.DependencyInjection StackTrace: at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection1 serviceDescriptors, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options) at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder) at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter1.CreateServiceProvider(Object containerBuilder) at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider() at Microsoft.Extensions.Hosting.HostBuilder.Build() at Aura.App.Program.Main(String[] args) in C:\Users\DRA11KS\source\repos\AuRA\Aura.App\Program.cs:line 16

This exception was originally thrown at this call stack: Inner Exception 1: InvalidOperationException: Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAuthorizationMessageHandler Lifetime: Transient ImplementationType: Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAuthorizationMessageHandler': Unable to resolve service for type 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.IAccessTokenProvider' while attempting to activate 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAuthorizationMessageHandler'. Inner Exception 2: InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.IAccessTokenProvider' while attempting to activate 'Microsoft.AspNetCore.Components.WebAssembly.Authentication.BaseAddressAuthorizationMessageHandler'.

How can I solve it? Thanks.

  • Related