【问题标题】:Blazor WebAssembly - How to create Policy-Based AuthorizationBlazor WebAssembly - 如何创建基于策略的授权
【发布时间】:2023-01-20 06:35:44
【问题描述】:

我一直在尝试向我的项目添加授权和权限。

我已经设法生成这样的数据库表:

 AspNetRoleClaims
 AspNetUserClaims
 AspNetRoles
 AspNetUsers
 ApsNetUserRoles

这些表是使用 PMC 生成的,我在使用 blazer web assembly 模板后提交了这些表。

在 PMC 中我输入:

 update-database

生成了上面描述的那些表。

所以当我使用:

         <AuthorizeView Roles="Admin"> 
        <div class="wrapper">

            <ContentLayout Title="@_greeting">
                <Card>
                    <CardContent>
                        Hi @context.User.Identity!.Name

                    </CardContent>
                </Card>

            </ContentLayout>

        </div>

        <div>

        </div>

    </AuthorizeView>

效果很好,只有管理员可以查看内容。

现在我的问题是如何添加基于策略的授权,我已经搜索以找到解决方案,但我尝试了示例但没有成功。

我想做的是找到一种无需任何逻辑即可添加基于策略的授权的方法,因此它内置于此表中,这可能吗?

或者有人可以分享我如何实现基于策略的授权吗?

这些是表中的数据:

政策正在尝试什么:

<AuthorizeView Policy="CanBuy">
    <div>hello</div>

</AuthorizeView>

但我得到错误:

【问题讨论】:

    标签: blazor-webassembly claims-based-identity


    【解决方案1】:

    我让它和这个一起工作。

    <AuthorizeView>
        @if (@context.User.Claims.Count(c => c.Value == Permissions.Products.Create) != 0)
        {
            <a class="btn btn-success" href="product/create">Create</a>
        }
        @if (@context.User.Claims.Count(c => c.Value == Permissions.Products.Edit) != 0)
        {
            <a class="btn btn-warning">Edit</a>
        }
        @if (@context.User.Claims.Count(c => c.Value == Permissions.Products.View) != 0)
        {
            <a class="btn btn-primary" href="product-list">View</a>
        }
        @if (@context.User.Claims.Count(c => c.Value == Permissions.Products.Delete) != 0)
        {
            <a class="btn btn-danger">Delete</a>
        }
    </AuthorizeView>
    

    请找到 repo 以供参考。 https://github.com/chhinsras/PermissionBlazorApp/blob/master/PermissionBlazorApp/Client/Pages/Product/ProductPage.razor

    【讨论】:

    • 您检索索赔的数据库设计是什么
    • @redoc01 默认 AspNet 标识
    【解决方案2】:

    您的解决方案没有任何意义,因为每个 @if 检查 @context.User...,如果不为空,则用户已通过身份验证,并且 AuthorizeView 是冗余的(没有策略属性)。

    我刚刚自己研究了这个,并提出了一个解决方案(在客户端启动时添加这段代码):

        services.AddApiAuthorization();
        services.AddAuthorizationCore(options =>
        {
            options.AddPolicy(
                "CanBuy",
                policy => policy.RequireClaim(
                    claimType,
                    claimValue));
        });
    

    仅将策略放在客户端上是没有意义的,因此您需要在服务器端执行相同的操作。

    【讨论】:

      【解决方案3】:

      接受的答案不是好的做法。

      下面是一个更好的解决方案,它遵循 ASP.NET Core 和 Blazor 应用程序的推荐方法:

      选项 1:在引导代码中进行验证;建议仅通过简单验证使用它。

      services.AddAuthorizationCore(options => {    
          options.AddPolicy("CanBuyPolicy", policy => 
                policy.RequireClaim("permission.canbuy", "CanBuy"));
      });
      

      或者

      services.AddAuthorizationCore(options => {    
          options.AddPolicy("CanBuyPolicy", policy => 
                policy.RequireRole("admin", "user"));
      });
      

      选项 2:设置策略处理程序,并引导它们;

      创建一个 Policy 类来执行您的要求的授权处理:

      public class UserCanBuyPolicy : IAuthorizationHandler
      {
          protected override Task HandleRequirementAsync(AuthorizationHandlerContext context)
          {
              //claim-based validation
              if (context.User.HasClaim("permission.canbuy", "CanBuy"))
                      context.Succeed(requirement);
      
              //role-based validation
              if (context.User.IsInRole("admin") || context.User.IsInRole("user"))
                      context.Succeed(requirement);
      
              return Task.CompletedTask;
          }
      
      }
      

      然后你需要在你的应用程序引导中注册你的策略:

      services.AddScoped<IAuthorizationHandler, UserCanBuyPolicy>();
      
      services.AddAuthorizationCore(options => {
          options.AddPolicy("CanBuyPolicy", policy => policy.Requirements.Add(UserCanBuyRequirement));
      });
      

      后一个选项提供了更大的灵活性,并且可以根据需要进行扩展以包含更多自定义逻辑。

      HTH

      【讨论】:

        猜你喜欢
        • 2021-11-05
        • 2021-09-17
        • 2020-09-23
        • 2021-02-08
        • 1970-01-01
        • 2019-10-03
        • 1970-01-01
        • 2020-02-16
        • 1970-01-01
        相关资源
        最近更新 更多