AuthorizationHandler 获取注入服务的新实例

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

我有一个带有自定义

AuthorizationHandler
IAuthorizationRequirement
的 Blazor 应用程序。片段来自
AuthorizationHandler

    internal class PermissionLevelAuthorizationHandler : AuthorizationHandler<PermissionLevelRequirement>
    {
        private readonly AuthService _authService;


        public PermissionLevelAuthorizationHandler(AuthService authService)
        {
            _authService= authService;
        }

        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionLevelRequirement requirement)
        {
            string? requiredResource = ((DefaultHttpContext?)context.Resource)?.Request.Path;
            int requiredLevel = requirement.Level;
            var canAccess = _authService.GetPermission(requiredResource, context.User, requiredLevel);
            if (canAccess) {
                context.Succeed(requirement);
            }
        }
}

AuthorizationHandler
已注入
AuthService
,它做了两件事:

  1. 从数据库中获取当前用户所属的所有组

  2. 检查(再次在数据库中)是否有任何用户组可以使用所需的权限级别访问所需的页面。

AuthService
AuthorizationHandler
都是范围服务。

由于

AuthService
必须为每个授权检查执行两次查询,因此我想将当前用户权限存储在
AuthService
中,并且仅在尚未加载权限时才联系数据库。

问题:问题是,似乎

AuthorizationHandler
每次都会获得
AuthService
的新实例,即使它们都在作用域内。因此我无法在服务中存储任何数据。为什么会这样?有什么办法可以解决这个问题吗?有没有更好的方法可以做到这一点?

据我所知,替代方案是:

  • 将声明存储在身份验证 cookie 中。这将使我的服务从执行 2 个查询减少到只执行第二个查询。但问题是,用户可以有很多组,因此 cookie 可能会变得太大。
  • 存储在浏览器的本地存储或会话存储中。我不想在那里存储权限。
  • 将所有用户的权限存储在单例服务中并定期刷新。这可行,但我不喜欢这样的事实:在我们更改权限后,用户必须等待刷新。

此外,身份验证是由中央应用程序完成的。因此身份验证 cookie 在多个应用程序之间共享。这使得存储变得更加复杂,因为我必须在所有应用程序上正确处理数据删除。这就是为什么最好的解决方案似乎是将数据存储在 DI 服务实例中。

.net dependency-injection service blazor authorization
1个回答
0
投票

Blazor Server 中的范围通常会根据连接进行持久化。
但是,如果我正确理解官方文档(请参阅https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/dependency-injection?view=aspnetcore-8.0#service-lifetime),有一个例外,那就是 “在客户端加载的组件之间传递消息”。

我假设您的逻辑是在这些电路消息的范围内执行的,因此,您的作用域服务的服务实例不会持久化,这可以解释您所经历的行为。

我建议实现单例缓存(就像您已经提到的那样)来安全地保存数据。

© www.soinside.com 2019 - 2024. All rights reserved.