尝试在我的所有控制器中应用授权过滤器,但未使用 IAuthorizationHandler [英] Trying to apply an authorisation filter in all my controllers but IAuthorizationHandler is not being used
问题描述
我尝试定义一个授权策略,以应用于我所有控制器的所有方法.我正在尝试遵循 此处给出的指南,在特定端点的授权"小节中替换我之前的 AuthorizeFilter
但它不起作用.
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.
在我的 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
的原因.
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
.
如果我调试,我不会像我期望的那样在处理程序处停下来.实际上,如果我在控制器中放置一个装饰器 [Authorize]
,我确实会停在那里,但是,正如我所提到的,我试图避免必须在所有控制器中编写这个装饰器.
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.
为什么不工作?谢谢!
推荐答案
我终于解决了.在 startup
中的 ConfigureServices
中:
I finally solved it. In ConfigureServices
in startup
:
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;
}
}
最后在 startup
中的 Configure
再次:
and finally in Configure
in the startup
again:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers().RequireAuthorization("UserIsRegistered");
});
总而言之,我的主要问题是使用 MapDefaultControllerRoute
而不是 MapControllers
...
To sum up, my main problem it was using MapDefaultControllerRoute
instead of MapControllers
...
这篇关于尝试在我的所有控制器中应用授权过滤器,但未使用 IAuthorizationHandler的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!