.net - 如何从 appsettings 动态设置 Blazor 中授权 View 标记或属性允许的角色或策略?

标签 .net asp.net-core blazor blazor-server-side .net-5

我正在尝试为一些应用程序创建共享布局。这些应用程序是 Blazor 服务器端应用程序。此布局有一个小菜单,可以通过 appsettings 文件进行配置。要求之一是我们能够根据应用程序设置中的 Active Directory 组列表显示或隐藏某些菜单项。以下是 JSON 设置的示例。

{
  "MenuItemName":"Protected Menu Item",
  "AllowedGroups": ["Administrator", "SpecialGroup", "SpecialGroup2"]
}

我相信我们需要在页面上使用 标记和/或 [Authorized] 属性,以确保用户无法导航到该页面。

我实际上如何动态填充这些标签?例如,采用 Microsoft 文档 ( https://learn.microsoft.com/en-us/aspnet/core/blazor/security/?view=aspnetcore-5.0#authorize-attribute-1 ) 中的以下示例。如何使用 Appsettings.json 中的设置替换 Roles="admin, superuser"?

<AuthorizeView Roles="admin, superuser">
    <p>You can only see this if you're an admin or superuser.</p>
</AuthorizeView>

在使用 [Authorized] 属性的另一个示例中,我如何从应用程序设置动态填充 Roles =“admin, superuser”部分?

@page "/"
@attribute [Authorize(Roles = "admin, superuser")]

<p>You can only see this if you're in the 'admin' or 'superuser' role.</p>

最佳答案

您可以设置一个策略来执行此操作: 这只是从 appsettings.json 中的 "AllowedGroups" 读取字符串数组,但它演示了基本原理。

{
  "AllowedGroups": [ "Administrator", "Moderator" ]
}
public class HasRolesFromConfigRequirement : IAuthorizationRequirement
{
    internal string[] allowedGroups;
    public HasRolesFromConfigRequirement(string[]? allowedGroups) => this.allowedGroups = allowedGroups;
}
public class HasRolesFromConfigHandler : AuthorizationHandler<HasRolesFromConfigRequirement>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        HasRolesFromConfigRequirement requirement)
    {
        var rolesRequired = requirement.allowedGroups;
        if (rolesRequired is null)
        {
            context.Fail();
        }
        else
        {
            var hasRequiredRole = rolesRequired.Where(role => context.User.IsInRole(role)).Any();
            if(hasRequiredRole)
            {
                context.Succeed(requirement);
            }
            else
            {
                context.Fail();
            }
        }
        return Task.CompletedTask;
    }
}
public static class AuthorizationOptionsPolicyExtensions
{
    public static void AddPolicies(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddScoped<IAuthorizationHandler, HasRolesFromConfigHandler>();
        services.AddAuthorizationCore(options => options.ConfigurePolicies(configuration));
    }

    public static AuthorizationOptions ConfigurePolicies(this AuthorizationOptions options, IConfiguration configuration)
    {
        var localConfiguration = configuration.Get<LocalConfiguration>();
        options.AddPolicy("HasARequiredRole", policy => policy.Requirements.Add(new HasRolesFromConfigRequirement(localConfiguration.AllowedGroups)));
        return options;
    }

}
<AuthorizeView Policy="HasARequiredRole">
    <div>
        Has A Required Role
    </div>
</AuthorizeView>
@page "/fetchdata"
@attribute [Authorize(Policy = "HasARequiredRole")]
...
[Authorize(Policy = "HasARequiredRole")]
public class WeatherForecastController : ControllerBase

.net6(rc1) repo .

我个人会考虑基于声明的权限。通过这种方式,您可以将应用程序资源分配给 claim 。然后将声明动态分配给角色或个人。

关于.net - 如何从 appsettings 动态设置 Blazor 中授权 View 标记或属性允许的角色或策略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69210022/

相关文章:

webassembly - Blazor 中有没有办法将 wasm-function(#) 映射回 c# 方法?

.net - Entity Framework Code First 如何确定多对多联结表名称?

.net - 适用于 Mac 和 Linux 的 .NET Core 中的 PEVerify 等效项在哪里?

sql - 将参数从 Access 中的另一个查询传递给查询

c# - Kestrel 和 OpenSSL 密码套件

winforms - 在 Windows 窗体中向 blazor 混合添加回调

Blazor(客户端)调用不同域上的 API

c# - 如何将参数传递给批处理文件?

c# - 如何从 ASP.NET Core 应用程序访问 Azure Active Directory 的其他数据?

angularjs - 如何在 MVC6 项目中安装 Angular2?