动态添加 Blazor 授权的策略声明

Rod*_*dik 1 authentication asp.net-authorization azure-authentication hosted-blazor-webassembly

我正在创建一个用于内部授权目的的身份验证和授权处理程序。我的目的是让我的同事能够轻松地将解决方案实施到他们自己的项目中。我们使用 Azure AD 进行身份验证,并使用 Azure 组进行授权。为了做到这一点,我觉得我一直在思考如何以有效的方式添加授权策略。

现在,我正在 Blazor WebAssembly 托管配置中的 Client 项目的 Program 类中通过官方描述的方式添加它:

            builder.Services.AddAuthorizationCore(options =>
                options.AddPolicy("PolicyName", policy =>
                {
                    policy.RequireClaim("ClaimType", "ClaimValue");
                })
            );
Run Code Online (Sandbox Code Playgroud)

这工作正常,但并不直观,因为任何给定的项目可能需要几种不同的策略

我还添加了一个自定义授权策略提供程序,如 Microsoft 的此文档中所述:

https://learn.microsoft.com/en-us/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-6.0

根据他们对该文档的描述,尤其是文档中的前几行,我认为这就是我正在寻找的内容。但如果没有专门手动添加每个策略,我似乎仍然无法让它按预期工作。

如果需要,我可以展示我的授权策略提供程序的自定义实现,但它与 Github 中的文档几乎完全相同。

小智 5

策略通常在应用程序启动时在StartupConfigureServices方法中注册。

\n
public void ConfigureServices(IServiceCollection services)    \n{\n    services.AddAuthorization(config =>\n    {\n        config.AddPolicy("IsDeveloper", policy => policy.RequireClaim("IsDeveloper","true"));\n       });\n}\n
Run Code Online (Sandbox Code Playgroud)\n

该策略IsDeveloper要求用户拥有IsDeveloper值为 的声明true

\n

您可以通过属性应用策略的角色Authorize

\n
[Route("api/[controller]")]\n[ApiController]\npublic class SystemController \n{\n    [Authorize(Policy = \xe2\x80\x9cIsDeveloper\xe2\x80\x9d)]\n    public IActionResult LoadDebugInfo()\n    {\n        // ...\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Blazors 指令和组件也可与策略配合使用。

\n
@page "/debug"\n@attribute [Authorize(Policy = "IsDeveloper")]\n< AuthorizeView Policy="IsDeveloper">\n    < p>You can only see this if you satisfy the IsDeveloper policy.< /p>\n< /AuthorizeView>\n
Run Code Online (Sandbox Code Playgroud)\n

管理更轻松

\n

使用基于角色的身份验证,如果我们有几个允许访问受保护资源的角色 - 让\xe2\x80\x99s 说adminmoderator。我们需要去他们被允许访问的每个区域并添加一个Authorize属性。

\n
[Authorize(Roles = "admin,moderator")]\n
Run Code Online (Sandbox Code Playgroud)\n

\xe2\x80\x99 最初看起来并不太糟糕,但是如果出现新需求并且第三个角色superuser需要相同的访问权限怎么办?我们现在需要巡视每个区域并更新所有角色。通过基于策略的身份验证,我们可以避免这种情况。

\n

我们可以在一个地方定义一个策略,然后将其应用到所有需要它的资源上。然后当需要添加额外的角色时,我们只需从中心点更新策略即可,而无需更新各个资源。

\n
 public void ConfigureServices(IServiceCollection services)\n{\n    services.AddAuthorization(config =>\n    {\n    config.AddPolicy("IsAdmin", policy => policy.RequireRole("admin", "moderator", "superuser"));\n    });\n}\n[Authorize(Policy = "IsAdmin")]\n
Run Code Online (Sandbox Code Playgroud)\n

创建共享策略

\n

Microsoft.AspNetCore.Authorization为此,我们需要从 NuGet 安装该包。

\n

之后创建一个名为Policies以下代码的新类。

\n
public static class Policies\n{\npublic const string IsAdmin = "IsAdmin";\npublic const string IsUser = "IsUser";\npublic static AuthorizationPolicy IsAdminPolicy()\n{\n    return new AuthorizationPolicyBuilder().RequireAuthenticatedUser()\n                                           .RequireRole("Admin")\n                                           .Build();\n}\n\npublic static AuthorizationPolicy IsUserPolicy()\n{\n    return new AuthorizationPolicyBuilder().RequireAuthenticatedUser()\n                                           .RequireRole("User")\n                                           .Build();\n}\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在这里,我们\xe2\x80\x99使用AuthorizationPolicyBuilder来定义每个策略,两者都要求用户经过身份验证,然后处于角色AdminUser角色中,具体取决于策略。

\n

配置服务器

\n

ConfigureServices在类中注册策略Startup。在现有调用下添加以下代码AddAuthentication

\n
services.AddAuthorization(config =>\n{\n    config.AddPolicy(Policies.IsAdmin, Policies.IsAdminPolicy());\n    config.AddPolicy(Policies.IsUser, Policies.IsUserPolicy());\n});\n
Run Code Online (Sandbox Code Playgroud)\n

注册每个策略并使用我们在类中定义的常量Policies来声明它们的名称,这样可以节省使用魔术字符串的麻烦。

\n

如果我们转向,SampleDataController我们可以更新Authorize属性以使用新IsAdmin策略而不是旧角色。

\n
[Authorize(Policy = Policies.IsAdmin)]\n[Route("api/[controller]")]\npublic class SampleDataController : Controller\n
Run Code Online (Sandbox Code Playgroud)\n

同样,我们可以使用名称常量来避免魔术字符串。

\n

配置客户端

\n

我们的服务器现在正在使用我们定义的新策略,剩下的\xe2\x80\x99s 要做的就是交换我们的 Blazor 客户端以也使用它们。

\n

ConfigureServices与服务器一样,我们\xe2\x80\x99 将首先在类中注册策略Startup。我们已经接到电话,AddAuthorizationCore所以我们只需要更新它。

\n
services.AddAuthorizationCore(config =>\n{\n    config.AddPolicy(Policies.IsAdmin, Policies.IsAdminPolicy());\n    config.AddPolicy(Policies.IsUser, Policies.IsUserPolicy());\n});\n
Run Code Online (Sandbox Code Playgroud)\n

在 中Index.razor,更新AuthorizeView组件以使用策略 - 仍然避免使用魔术字符串。

\n
< AuthorizeView Policy="@Policies.IsUser">\n    < p>You can only see this if you satisfy the IsUser policy.< /p>\n< /AuthorizeView>\n< AuthorizeView Policy="@Policies.IsAdmin">\n    < p>You can only see this if you satisfy the IsAdmin policy.< /p>\n< /AuthorizeView>\n
Run Code Online (Sandbox Code Playgroud)\n

最后更新FetchData.razorsAuthorize属性。

\n
@attribute [Authorize(Policy = Policies.IsAdmin)]\n
Run Code Online (Sandbox Code Playgroud)\n

参考这里

\n