尝试在我的所有控制器中应用授权过滤器,但未使用IAuthorizationHandler



我尝试定义一个授权策略,以应用于所有控制器的所有方法。我正在尝试按照此处在"特定端点的授权"小节中给出的准则来替换我以前的AuthorizeFilter但它不起作用。

在我的Startup中,我有:

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

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>();

我有一个要求:

public class MyRequirement : IAuthorizationRequirement
{
public EntityType MyParams { get; private set; }
public MyRequirement(MyParams myParams) { MyParams = myParams; }
}

和一个处理程序:

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.       
}
}

在我的控制器中,我没有放置任何装饰器,因为我想将此授权策略应用于我的所有方法,这就是我覆盖DefaultPolicy的原因。

如果我调试,我不会像预期的那样停留在处理程序上。实际上,如果我在控制器中放置一个装饰器[Authorize],我确实会停在那里,但是,正如我所提到的,我试图避免在所有控制器中编写这个装饰器。

为什么不工作?谢谢!

我的理解是,为了使用默认策略,需要[Authorize]属性。当我需要以这种方式保护所有端点时,我通常会做的是创建一个具有此属性的抽象基本控制器,然后让我的其他控制器继承此属性。

例如:

基本控制器

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

其他控制器:

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

我终于解决了。在startupConfigureServices

services.AddAuthorization(options =>
{
options.AddPolicy(
"UserIsRegistered",
new AuthorizationPolicyBuilder()
.AddRequirements(new RegistrationRequirement())
.Build());
});

然后我定义了RegistrationRequirement

public class RegistrationRequirement : IAuthorizationRequirement
{
}

然后我定义了RegistrationAuthorizationHandler

public class RegistrationAuthorizationHandler : AuthorizationHandler<RegistrationRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RegistrationRequirement requirement)
{
---> LOGIC I WANT TO CHECK
if (WHATEVER)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
} 

最后在startupConfigure再次:

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers().RequireAuthorization("UserIsRegistered");
});

总而言之,我的主要问题是使用MapDefaultControllerRoute而不是MapControllers......

试试这个:

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?}");
});
}

最新更新