Trying to apply an authorisation filter in all my controllers bug IAuthorizationHandler is not being used

喜夏-厌秋 提交于 2020-01-06 08:06:08

问题


I try to define an authorization policy to be applied in all methods of all my controllers. I am trying to follow the guidelines given here, in "Authorization for specific endpoints" subsection to substitute my previous AuthorizeFilter but it does not work.

In my Startup I have:

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapDefaultControllerRoute().RequireAuthorization();
});

In ConfigureServices:

services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
    .AddAzureADBearer(options => this.Configuration.Bind("AzureAd", options));

services.AddAuthorization(options =>
{
    options.DefaultPolicy = new AuthorizationPolicyBuilder()
        .AddRequirements(new MyRequirement(MyParams))
        .Build();
});
(...)
    services.AddTransient<IAuthorizationHandler, MyAuthorizationHandler>();

And I have a Requirement:

public class MyRequirement : IAuthorizationRequirement
{
    public EntityType MyParams { get; private set; }

    public MyRequirement(MyParams myParams) { MyParams = myParams; }
}

and a Handler:

public class MyAuthorizationHandler : AuthorizationHandler<MyRequirement>
{
    private readonly ILogger<MyAuthorizationHandler> logger;
    private readonly IHttpContextAccessor httpContextAccessor;

    public MyAuthorizationHandler(IHttpContextAccessor httpContextAccessor, ILogger<MyAuthorizationHandler> logger)
    {
        this.httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
        this.logger = logger;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyRequirement requirement)
    {
---> Some things. I don't get here when I debug.       
    }
}

In my controllers I do NOT put any decorator, because I want to apply this authorization policy to ALL my methods, and that's why I override the DefaultPolicy.

If I debug, I do not stop at the Handler as I expect. Actually, if I put a decorator [Authorize] in the controller, I do stop there but, as I mentioned, I'm trying to avoid having to write this decorator in all the controllers.

Why is is not working? Thank you!


回答1:


My understanding is that the [Authorize] attribute is required in order to use even the default policy. What I normally do when I need to protect all my endpoints in this way is to create an abstract base controller with this attribute and then have my other controllers inherit from this.

For example:

Base controller

[Authorize]
public abstract class MyBaseController : Controller //use Controller for mvc controller or ControllerBase for api controller
{
//base controller methods and properties
}

Other controllers:

public class MyOtherController : MyBaseController 
{
//controller methods and properties
}




回答2:


Try this:

public void ConfigureServices(IServiceCollection services)
{         
    services.AddHttpContextAccessor();
    services.AddTransient<IAuthorizationHandler, MyAuthorizationHandler>();

    services.AddControllersWithViews(config =>
    {
        var policy = new AuthorizationPolicyBuilder()
                .AddRequirements(new MyRequirement(MyParams))
            .Build();
        config.Filters.Add(new AuthorizeFilter(policy));
    });

    services.AddDbContext<MvcProj3Context>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("MvcProj3Context")));
}

// 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("/Home/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.UseAuthentication();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");

    });
}


来源:https://stackoverflow.com/questions/59503646/trying-to-apply-an-authorisation-filter-in-all-my-controllers-bug-iauthorization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!