Blazor 文件夹授权不起作用,允许未登录的用户查看内容
Blazor folder authorization not working, allows non-logged in users to see content
最新的 blazor .NET blazor。
Program.cs
using APICommon;
using Common.Settings;
using EventApiService;
using Events.Application.Commands.Coins;
using FluentValidation;
using Identity.Application.Commands;
using Identity.Persistence;
using MediatR;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Serilog;
var builder = WebApplication.CreateBuilder(args);
//Serilog
builder.WebHost.UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext());
//code removed
builder.Services.AddCustomAuthorization(dbSettings);
builder.Services.AddHttpClient();
builder.Services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/admin", "Administrators");
options.Conventions.AuthorizeFolder("/client", "Owners");
}
);
builder.Services.AddServerSideBlazor();
builder.Services.AddTelerikBlazor();
builder.Services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
internal static class ExtensionMethods
{
public static IServiceCollection AddCustomAuthorization(this IServiceCollection services,
DatabaseSettings dbSettings)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(dbSettings.IdentityConnectionString));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddDefaultIdentity<ApplicationUser>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.Password.RequiredLength = 6;
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequiredUniqueChars = 0;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
})
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
return services;
}
}
以上假设是为了确保只有授权的“所有者”角色才能看到 /client 或其中的任何页面,但即使我不登录,我也可以点击 /client 并查看其内容。
我认为你不应该在 Blazor 中使用它:
builder.Services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/admin", "Administrators");
options.Conventions.AuthorizeFolder("/client", "Owners");
}
);
相反,您应该应用授权属性,如下所示:
[Authorize(Roles = "Administrators")]
ya i have the above in one of the pages and it works, but I dont want to repeat this in every page, and in case a page is added in the future i want to make sure be default its protected if its under the folder
在这种情况下,您可以将 Authorize 属性放在 _Imports.razor 文件中,从而为您的所有页面启用该属性。您还可以使用 Authorize 属性定义组件基 class,并从该 class 派生所有组件页面。这种技术更为常见,因为您可以将所有页面的其他共同点放在基础 class 中。这就是 Blazor 的方法。您尝试做的实际上在 MVC 或 Razor 页面中很常见,但不适用于 Blazor。
Blazor 不支持授权“文件夹”。您将需要授权组件。
处理此问题的一种方法是对所有管理元素使用 AdminPanelComponent
,并在该组件上应用管理授权规则。
由于您使用的是 Blazor 服务器,因此您可以匹配路由并使用中间件应用授权。示例:
app.Use(async (context, next) =>
{
if(context.Request.Path.StartsWithSegments("/admin", System.StringComparison.OrdinalIgnoreCase))
{
if (!context.User.IsAdministrator()) // ext. method... replace with your own logic
{
await context.ForbidAsync();
return;
}
}
if(context.Request.Path.StartsWithSegments("/client", System.StringComparison.OrdinalIgnoreCase))
{
if (!context.User.IsOwner())
{
await context.ForbidAsync();
return;
}
}
await next.Invoke();
});
(如果您愿意,可以将其重构为 own middleware class。)
最新的 blazor .NET blazor。 Program.cs
using APICommon;
using Common.Settings;
using EventApiService;
using Events.Application.Commands.Coins;
using FluentValidation;
using Identity.Application.Commands;
using Identity.Persistence;
using MediatR;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Serilog;
var builder = WebApplication.CreateBuilder(args);
//Serilog
builder.WebHost.UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext());
//code removed
builder.Services.AddCustomAuthorization(dbSettings);
builder.Services.AddHttpClient();
builder.Services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/admin", "Administrators");
options.Conventions.AuthorizeFolder("/client", "Owners");
}
);
builder.Services.AddServerSideBlazor();
builder.Services.AddTelerikBlazor();
builder.Services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
internal static class ExtensionMethods
{
public static IServiceCollection AddCustomAuthorization(this IServiceCollection services,
DatabaseSettings dbSettings)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(dbSettings.IdentityConnectionString));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddDefaultIdentity<ApplicationUser>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
options.Password.RequiredLength = 6;
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequiredUniqueChars = 0;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
})
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
return services;
}
}
以上假设是为了确保只有授权的“所有者”角色才能看到 /client 或其中的任何页面,但即使我不登录,我也可以点击 /client 并查看其内容。
我认为你不应该在 Blazor 中使用它:
builder.Services.AddRazorPages(options =>
{
options.Conventions.AuthorizeFolder("/admin", "Administrators");
options.Conventions.AuthorizeFolder("/client", "Owners");
}
);
相反,您应该应用授权属性,如下所示:
[Authorize(Roles = "Administrators")]
ya i have the above in one of the pages and it works, but I dont want to repeat this in every page, and in case a page is added in the future i want to make sure be default its protected if its under the folder
在这种情况下,您可以将 Authorize 属性放在 _Imports.razor 文件中,从而为您的所有页面启用该属性。您还可以使用 Authorize 属性定义组件基 class,并从该 class 派生所有组件页面。这种技术更为常见,因为您可以将所有页面的其他共同点放在基础 class 中。这就是 Blazor 的方法。您尝试做的实际上在 MVC 或 Razor 页面中很常见,但不适用于 Blazor。
Blazor 不支持授权“文件夹”。您将需要授权组件。
处理此问题的一种方法是对所有管理元素使用 AdminPanelComponent
,并在该组件上应用管理授权规则。
由于您使用的是 Blazor 服务器,因此您可以匹配路由并使用中间件应用授权。示例:
app.Use(async (context, next) =>
{
if(context.Request.Path.StartsWithSegments("/admin", System.StringComparison.OrdinalIgnoreCase))
{
if (!context.User.IsAdministrator()) // ext. method... replace with your own logic
{
await context.ForbidAsync();
return;
}
}
if(context.Request.Path.StartsWithSegments("/client", System.StringComparison.OrdinalIgnoreCase))
{
if (!context.User.IsOwner())
{
await context.ForbidAsync();
return;
}
}
await next.Invoke();
});
(如果您愿意,可以将其重构为 own middleware class。)