我在 .NET 6.0 中开发了一个 OData 端点,我需要添加一个自定义参数化授权过滤器。 感谢这个 documentation,我创建了自定义 AuthorizeAttribute、IAuthorizationPolicyProvider 和 AuthorizationHandler 及其要求。 问题是,当我执行请求时,HandleRequirementAsync函数被调用了三次:
我没有找到很多关于这个 AuthorizationFilterContextSealed 类的信息...
有人知道为什么要打这些电话吗?
有办法避免它们吗?否则,管理它们的最佳实践是什么?因为我无法将 context.Resource 转换为 AuthorizationFilterContextSealed,因为此类是内部的。
谢谢:)
我的 .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);