How to authorize user#39;s role in client side of blazor wasm?(如何授权用户在Blazor WASM客户端的角色?)
问题描述
环境
- ASP.NET Core 5.0
 - Blazor WebAssembly应用程序(ASP.NET核心托管)
 - ASP.NET核心标识(使用Identity Server 4)
 
问题
我希望在服务器端和客户端之间使用基于角色的授权。
我可以正确登录,UserManager.IsInRoleAsync(user, "admin")在服务器端返回True。
但@attribute [Authorize(Roles = "admin")]和<AuthorizeView Roles="admin">都不能在客户端运行。同时User.Identity.IsInRole("admin")在客户端返回FALSE。
如何获取用户在客户端的角色?
代码
Server.csproj
// Startup.ConfigureServices()
services.AddDefaultIdentity<ApplicationUser>(options =>
{
    options.SignIn.RequireConfirmedAccount = true;
    options.Password.RequiredLength = 6;
    options.Password.RequiredUniqueChars = 2;
    options.Password.RequireNonAlphanumeric = false;
    options.User.RequireUniqueEmail = true;
})
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
    .AddIdentityServerJwt();
// Startup.Configure()
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
// RolesController.Get()
var userid = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
var currentUser = await userManager.FindByIdAsync(userid);
return await userManager.IsInRoleAsync(currentUser, "admin"); // Returns True
客户端.csproj
// Program.Main()
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("WebAppIdentity.ServerAPI"));
builder.Services.AddApiAuthorization();
// Test.razor
<AuthorizeView Roles="admin">
    <Authorizing>
        Authorizing...
    </Authorizing>
    <NotAuthorized>
        You are not an admin. // Always here
    </NotAuthorized>
    <Authorized>
        Hello, admin!
    </Authorized>
</AuthorizeView>
<button @onclick="ShowInfo">Show Info</button>
<p>@infoString</p>
@code
{
    [CascadingParameter]
    private Task<AuthenticationState> stateTask { get; set; }
    private string infoString { get; set; }
    private async void ShowInfo()
    {
        var user = (await stateTask).User;
        infoString = $"Is admin: {user.IsInRole("admin")}"; // Always False
    }
}
推荐答案
当前有two accepted ways正在处理此问题。
第一个
#1通过调用AddRoles将身份配置为使用角色
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();
#2配置标识服务器以将角色声明放入id令牌和访问令牌中,并阻止JwtSecurityTokenHandler中角色的默认映射。
services.AddIdentityServer()
    .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
        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");
#3在您的Blazor应用程序上使用[Authorize(Roles=";admin";)]或您的应用程序定义的任何其他角色。
#4在您的受保护资源API上使用[Authorize(Roles=";admin";)]或您的应用程序定义的任何其他角色。
第二个
#1添加类以配置选项。客户端上的UserOptions.RoleClaim
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.Extensions.Options;
namespace App.Client.Services
{
    public class ApiAuthorizationOptionsConfiguration
        : IPostConfigureOptions<RemoteAuthenticationOptions<ApiAuthorizationProviderOptions>>
    {
        public void Configure(RemoteAuthenticationOptions<ApiAuthorizationProviderOptions> options)
        {
            options.UserOptions.RoleClaim ??= "role";
        }
        public void PostConfigure(string name, RemoteAuthenticationOptions<ApiAuthorizationProviderOptions> options)
        {
            if (string.Equals(name, Options.DefaultName))
            {
                Configure(options);
            }
        }
    }
}
#2修改Program.cs文件以调用ApiAuthorizationOptionsConfiguration并配置角色声明。
using App.Client.Services;
...
namespace App.Client
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            ...
            builder.Services.AddAuthorizationCore();
            builder.Services.AddApiAuthorization();
            builder.Services.TryAddEnumerable(
                ServiceDescriptor.Singleton<
                    IPostConfigureOptions<RemoteAuthenticationOptions<ApiAuthorizationProviderOptions>>,
                    ApiAuthorizationOptionsConfiguration>());
            ...
        }
    }
}
                        这篇关于如何授权用户在Blazor WASM客户端的角色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何授权用户在Blazor WASM客户端的角色?
				
        
 
            
        基础教程推荐
- 将事件 TextChanged 分配给表单中的所有文本框 2022-01-01
 - 是否可以在 asp classic 和 asp.net 之间共享会话状态 2022-01-01
 - 全局 ASAX - 获取服务器名称 2022-01-01
 - 错误“此流不支持搜索操作"在 C# 中 2022-01-01
 - 首先创建代码,多对多,关联表中的附加字段 2022-01-01
 - 从 VS 2017 .NET Core 项目的发布目录中排除文件 2022-01-01
 - 在 VS2010 中的 Post Build 事件中将 bin 文件复制到物 2022-01-01
 - 经典 Asp 中的 ResolveUrl/Url.Content 等效项 2022-01-01
 - 如何动态获取文本框中datagridview列的总和 2022-01-01
 - JSON.NET 中基于属性的类型解析 2022-01-01
 
    	
    	
    	
    	
    	
    	
    	
    	
						
						
						
						
						
				
				
				
				