【发布时间】:2022-01-04 18:45:14
【问题描述】:
我有一个 .NET 5.0 Blazor 客户端应用程序,但无法使用 [Authorize(Roles="Admin")] 和 AuthorizeView 标记。
我也搭建了身份页面:
我正在使用使用 Cosmos Db 的自定义身份实现:https://github.com/pierodetomi/efcore-identity-cosmos
我知道 Blazor 客户端项目模板中的角色授权是一个问题:https://github.com/dotnet/AspNetCore.Docs/issues/17649#issuecomment-612442543
我尝试了上述 Github 问题线程和以下 SO 答案中提到的解决方法:https://stackoverflow.com/a/64798061/6181928
...不过,我无法让它工作。
具有讽刺意味的是,IsInRoleAsync 方法在登录到应用程序后甚至都没有被调用。我在自定义 CosmosUserStore 类中对其实现应用了一个断点,它没有被命中。
使用管理员用户登录应用程序后,浏览器控制台会显示:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddCosmosIdentity<MyDbContext, IdentityUser, IdentityRole>(
// Auth provider standard configuration (e.g.: account confirmation, password requirements, etc.)
options => options.SignIn.RequireConfirmedAccount = true,
options => options.UseCosmos(
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
databaseName: "xxxxxxxxxxxxxxxxxxxxxxxxx"
),
addDefaultTokenProviders: true
).AddDefaultUI().AddRoles<IdentityRole>();
services.AddScoped<IUsersRepository, UsersRepository>();
services.AddIdentityServer().AddApiAuthorization<IdentityUser, MyDbContext>(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");
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddControllersWithViews();
services.AddRazorPages();
}
Program.cs
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddHttpClient("IdentityDocApp.ServerAPI", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("IdentityDocApp.ServerAPI"));
builder.Services.AddHttpClient();
builder.Services.AddScoped<IManageUsersService, ManageUsersService>();
builder.Services.AddBlazorTable();
builder.Services.AddApiAuthorization();
builder.Services.AddApiAuthorization(options =>
{
options.UserOptions.RoleClaim = "role";
});
await builder.Build().RunAsync();
}
}
NavMenu.razor
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<AuthorizeView Roles="Admin">
<li class="nav-item px-3">
<NavLink class="nav-link" href="users">
<span class="oi oi-person" aria-hidden="true"></span> Users
</NavLink>
</li>
</AuthorizeView>
</ul>
ManageUsers.razor
数据库在 UserRoles 集合中有正确的数据。没有问题。
那么,可能是什么问题?我做错了什么?
更新:
这很尴尬,但我在自定义用户存储中的IsInRoleAsync 实现不正确。一旦我修复它,问题就消失了。
我只在服务器端的Startup.cs使用如下代码:
services.AddIdentityServer()
.AddApiAuthorization<IdentityUser, MyDbContext>(options =>
{
options.IdentityResources["openid"].UserClaims.Add("name");
options.ApiResources.Single().UserClaims.Add("name");
options.IdentityResources["openid"].UserClaims.Add("role");
options.ApiResources.Single().UserClaims.Add("role");
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
在客户端的Program.cs我只使用builder.Services.AddApiAuthorization();
感谢@MrC aka Shaun Curtis 让我知道问题出在服务器端。
【问题讨论】:
-
请将您的
App.razor添加到您的问题中。 -
@MrCakaShaunCurtis
App.razor已添加问题。 -
谢谢。从登录过程返回您的应用程序后,您是否在
App中点击?或者你登陆的是哪个页面? -
谢谢,@MrCakaShaunCurtis。以管理员用户登录后,它登陆
Index.razor。屏幕截图:ibb.co/Wthd42b 当我尝试访问包含 Authorize 和 AuthorizeView 标签的“/users”时,它给出“您无权访问此资源”。截图:ibb.co/SnVnqB9 -
查看答案以获得更多测试。这不是答案,但您不能将代码放在评论中!
标签: authorization blazor .net-5 blazor-webassembly asp.net-authorization