MiniProfiler ASP.NET Core - ShouldProfile на основе роли пользователя

У меня установлен MiniProfiler в приложении ASP.NET Core. Профилирование работает нормально.

Однако я хочу, чтобы только администраторы могли профилировать.

У меня в ConfigureServices есть:

services.AddMiniProfiler(options =>
{
    options.ShouldProfile = request =>
        request.HttpContext.User.IsInRole("Admin");
});

Проблема в том, что идентификатор пользователя не загружен в этот метод.
Свойство User.Identity.Name имеет значение null, и нет никаких заявлений.
Я предполагаю, что этот вызов происходит до того, как эта информация будет заполнена?

Как я могу профилировать на основе личности пользователя?


person Xavier Poinas    schedule 25.10.2020    source источник


Ответы (1)


Вам необходимо знать, что согласно документы метод ClaimsPrincipal.IsInRole() проверяет утверждения типа ClaimsIdentity.RoleClaimType. Убедитесь, что вы добавили утверждения ролей.

Вот рабочая демонстрация, за которой вы можете следить:

1. Успешно зарегистрируйте пользователя с именем [email protected].

2. Сгенерируйте роль и добавьте роль с утверждениями к пользователю:

public async Task CreateRolesandUsers()
{
    bool x = await _roleManager.RoleExistsAsync("Admin");
    if (!x)
    {
        // first we create Admin role   
        var role = new IdentityRole();
        role.Name = "Admin";
        await _roleManager.CreateAsync(role);
         
         //must add the claim,otherwise IsInRole would always be false..
        _roleManager.AddClaimAsync(role, new Claim(ClaimTypes.AuthorizationDecision, "Admin")).Wait();
    }
    var user = _userManager.FindByNameAsync(User.Identity.Name).Result;
    if (user != null)
    {
        var result1 = await _userManager.AddToRoleAsync(user, "Admin");
    }
}

2.Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddIdentity<IdentityUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultUI();

    services.AddMiniProfiler(options =>
    {
        options.RouteBasePath = "/profiler";
        options.ShouldProfile = request =>
request.HttpContext.User.IsInRole("Admin");
        options.SqlFormatter = new StackExchange.Profiling.SqlFormatters.InlineFormatter();
    });
    services.AddControllersWithViews();
    services.AddRazorPages();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();  //be sure add this
    app.UseAuthorization();  

    app.UseMiniProfiler();     //add this before UseEndpoints

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
        endpoints.MapRazorPages();
    });
}

Результат:

введите описание изображения здесь

person Rena    schedule 26.10.2020
comment
Благодаря вашему примеру я понял, что моя проблема заключалась в том, что я звонил UseMiniProfiler перед UseAuthentication и UseAuthorization. Переместив его после того, как они исправили это! Спасибо. - person Xavier Poinas; 28.10.2020