【问题标题】:Use Authorization Roles and Policies in Blazor WebAssembly with Identity?在 Blazor WebAssembly 中使用身份验证角色和策略?
【发布时间】:2020-07-23 23:10:50
【问题描述】:

我正在使用一个 Blazor WebAssembly 3.2-preview3 应用程序,该应用程序使用 Identity 创建了以下 3 个项目:

App.Client
App.Server
App.Shared

我的IdentityUser 实现称为AppUser,我的ApiAuthorizationDbContext 实现称为AppDb

我有一个名为Admin 的角色已分配给管理员,还有一个名为RequireAdmin 的策略用于检查Admin 角色。但是,当我尝试在App.Client 中使用AuthorizeView 并与管理员一起查看页面时,它不会显示链接。

<AuthorizeView Policy="RequireAdmin">
    <Authorized>
        <a class="nav-link" href="admin">Admin</a>
    </Authorized>
</AuthorizeView>

如何在我的 Blazor WebAssembly 应用程序中启用角色和策略?

【问题讨论】:

    标签: asp.net-identity blazor blazor-client-side


    【解决方案1】:

    1.在 App.Shared 中创建角色和策略

    Microsoft.AspNetCore.Authorization 包添加到App.Shared 项目中

    App.Shared 项目中添加以下 2 个类来定义将由客户端和服务器使用的角色和策略。

    Shared/RoleTypes.cs

    namespace App.Shared
    {
        public static class RoleTypes
        {
            public const string Admin = "Admin";
        }
    }
    

    Shared/PolicyTypes.cs

    using Microsoft.AspNetCore.Authorization;
    
    namespace App.Shared
    {
        public static class PolicyTypes
        {
            public const string RequireAdmin = "RequireAdmin";
    
            public static AuthorizationOptions AddAppPolicies(this AuthorizationOptions options)
            {
                options.AddPolicy(RequireAdmin, policy =>
                    policy.RequireRole(RoleTypes.Admin));
                return options;
            }
        }
    }
    

    2。在 App.Server 中配置服务

    通过调用刚刚在App.Shared 中定义的扩展方法,修改App.Server 项目中的Startup.cs 文件以添加您的策略。

    同时修改它以在openid 范围内包含role 声明。

    服务器/Startup.cs

    using App.Shared;
    ...
    
    namespace App.Server
    {
        public class Startup
        {
    
            ...
    
            public void ConfigureServices(IServiceCollection services)
            {
                ...
    
                services.AddDefaultIdentity<AppUser>(options =>
                    {
                        options.SignIn.RequireConfirmedAccount = true;
                    })
                    .AddRoles<IdentityRole>()
                    .AddEntityFrameworkStores<AppDb>();
    
                services.AddIdentityServer()
                    .AddApiAuthorization<AppUser, AppDb>(options =>
                    {
                        // https://github.com/dotnet/AspNetCore.Docs/issues/17649
                        options.IdentityResources["openid"].UserClaims.Add("role");
                        options.ApiResources.Single().UserClaims.Add("role");
                    });
                // Need to do this as it maps "role" to ClaimTypes.Role and causes issues
                JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
    
                services.AddAuthentication()
                    .AddIdentityServerJwt();
    
                services.AddAuthorization(options => options.AddAppPolicies());
    
                ...
            }
    
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                ...
    
                app.UseAuthentication();
                app.UseAuthorization();
                app.UseIdentityServer();
    
                ...
            }
        }
    }
    

    3.在 App.Client 中配置服务

    通过调用刚刚在App.Shared 中定义的扩展方法,修改App.Client 项目中的Program.cs 文件以添加您的策略。还要修改AddApiAuthorization 以配置role 声明。

    Client/Program.cs

    using App.Client.Services;
    using App.Shared;
    ...
    
    namespace App.Client
    {
        public class Program
        {
            public static async Task Main(string[] args)
            {
                ...
    
                builder.Services.AddAuthorizationCore(options => options.AddAppPolicies());
                // 2 calls to AddApiAuthorization are necessary in 3.2-preview3
                // should be fixed in 3.2-preview4
                // https://github.com/dotnet/aspnetcore/issues/19854
                // https://github.com/dotnet/AspNetCore.Docs/issues/17649#issuecomment-612442543
                builder.Services.AddApiAuthorization();
                builder.Services.AddApiAuthorization(options =>
                {
                    options.UserOptions.RoleClaim = "role";
                });
    
                ...
            }
        }
    }
    

    【讨论】:

    • 谢谢。我现在唯一的问题是用户是否有多个角色。如果您检查 JWT 令牌,角色将作为数组返回:“role”:[“Clinician”,“Patient”] 这在客户端不起作用
    猜你喜欢
    • 2020-11-02
    • 2013-07-24
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-20
    • 1970-01-01
    • 2015-01-09
    相关资源
    最近更新 更多