为什么我的自定义 AuthorizationHandler 使用 AuthorizationFilterContextSealed 对象作为 context.Resource 执行两次?

问题描述 投票:0回答:1

我在 .NET 6.0 中开发了一个 OData 端点,我需要添加一个自定义参数化授权过滤器。 感谢这个 documentation,我创建了自定义 AuthorizeAttributeIAuthorizationPolicyProviderAuthorizationHandler 及其要求。 问题是,当我执行请求时,HandleRequirementAsync函数被调用了三次:

  • 第一次使用 DefaultHttpContext 对象作为 context.Resource
  • 另外两次使用 AuthorizationFilterContextSealed 对象作为 context.Resource

我没有找到很多关于这个 AuthorizationFilterContextSealed 类的信息...

有人知道为什么要打这些电话吗?

有办法避免它们吗?否则,管理它们的最佳实践是什么?因为我无法将 context.Resource 转换为 AuthorizationFilterContextSealed,因为此类是内部的。

谢谢:)

asp.net-mvc odata .net-6.0 asp.net-authorization
1个回答
0
投票

我的 .NET8 应用程序也遇到过类似的问题。我添加了一个全局 AuthorizeFilter 以确保用户具有特定角色。我的控制器上还有一个带有自定义策略的 Authorize 属性。在调试时,我发现对于控制器操作的每个请求,我的 AuthorizationHandler 中的 HandleRequirementAsync 被执行两次。第一次,context.Resource 是预期的 DefaultHttpContext。第二次是AuthorizationFilterContextSealed

我在 github 上遇到了以下问题,它解释了该问题并提供了解决方案。 https://github.com/dotnet/aspnetcore/issues/32518

我引用Pranav的回答作为参考。

是的,这是设计使然。从 3.1 开始,授权属性由授权中间件处理,而不是由 MVC 的授权过滤器评估。但是,如果您显式添加 AuthorizationFilter,它将单独执行。

不要添加 AuthorizationFilter,而是考虑使用 using 端点上需要授权:例如

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

这可以替代添加全局身份验证过滤器。

应用上述解决方案后,每个请求仅调用我的AuthorizationHandler一次。

除了上述之外,为了对基于属性的路由应用相同的策略,我必须在显式调用 MapControllers() 的结果上调用 RequireAuthorize。如果您使用 .NET8,则可以在 WebApplicationBuilder 返回的 WebApplication 对象 (app) 上调用 Map* 方法。

app.MapControllers()
    .RequireAuthorization(policy);
© www.soinside.com 2019 - 2024. All rights reserved.