0


I am trying to add a handler to my services in Startup.cs. Doing this will give me the following error:
Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Authorization.IAuthorizationService Lifetime: Transient ImplementationType: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService': Unable to resolve service for type 'Microsoft.AspNetCore.Http.IHttpContextAccessor' while attempting to activate 'ApiPortal.Classes.PolicyAuthorizationHandler')

Here is my Startup.cs ConfigureServices:

 public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")); services.Configure<OpenIdConnectOptions>("azure", options => { var existingOnTokenValidatedHandler = options.Events.OnTokenValidated; options.Events.OnTokenValidated = async context => { await existingOnTokenValidatedHandler(context); await context.HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, context.Principal); }; var existingOnUserInformationReceived = options.Events.OnUserInformationReceived; options.Events.OnUserInformationReceived = async context => { await existingOnUserInformationReceived(context); }; }); services.AddAuthorization(options => { options.AddPolicy("AzureAccount", policy_builder => policy_builder.AddRequirements(new PolicyRequirement())); }); services.AddScoped<IAuthorizationHandler, PolicyAuthorizationHandler>(); services.AddControllersWithViews(options => { var policy = new AuthorizationPolicyBuilder() .RequireAuthenticatedUser() .Build(); options.Filters.Add(new AuthorizeFilter(policy)); }); services.AddRazorPages() .AddMicrosoftIdentityUI(); } 

Here is my PolicyAuthorizationHandler.cs:

 public class PolicyAuthorizationHandler : AuthorizationHandler<PolicyRequirement> { readonly IHttpContextAccessor _contextAccessor; public PolicyAuthorizationHandler(IHttpContextAccessor ca) { _contextAccessor = ca; } protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PolicyRequirement requirement) { if (context.Resource is AuthorizationFilterContext filterContext) { var area = ""; var controller = (filterContext.RouteData.Values["controller"] as string)?.ToLower(); var action = (filterContext.RouteData.Values["action"] as string)?.ToLower(); var id = ""; if (await requirement.Pass(context, _contextAccessor, area, controller, action, id)) { context.Succeed(requirement); } } if (context.Resource is DefaultHttpContext httpContext) { var area = ""; var controller = httpContext.Request.RouteValues["controller"].ToString(); var action = httpContext.Request.RouteValues["action"].ToString(); var id = ""; if (await requirement.Pass(context, _contextAccessor, area, controller, action, id)) { context.Succeed(requirement); } } } } 

Here is my PolicyRequirement.cs class:

 public class PolicyRequirement : IAuthorizationRequirement { IHttpContextAccessor _contextAccessor; AuthorizationHandlerContext _context; public async Task<bool> Pass(AuthorizationHandlerContext context, IHttpContextAccessor contextAccessor, string area, string controller, string action, string id) { _context = context; _contextAccessor = contextAccessor; bool authorized = false; //authorization logic goes here string email = contextAccessor.HttpContext.User.Identity.Name; if (email == "[email protected]") authorized = true; return await Task.FromResult(authorized); } } 

I have already tried changing services.AddScoped<IAuthorizationHandler, PolicyAuthorizationHandler>() to services.AddTransient<IAuthorizationHandler, PolicyAuthorizationHandler>() and services.AddSingleton<IAuthorizationHandler, PolicyAuthorizationHandler>(). These don't seem to work.

I have also taken a look at this and this thread, but I can't seem to find a solution for my problem here as well.

What am I doing wrong and what can I do to fix this error? Thanks in advance.

1 Answer 1

2

This error means that PolicyAuthorizationHandler class depends on a service of type IHttpContextAccessor, but that service is not registered in the service container.

you need to register IHttpContextAccessor in ConfigureServices by adding line services.AddHttpContextAccessor();

and after this, you can pass IHttpContextAccessor to the constructor of PolicyAuthorizationHandler `

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.