I have MiniProfiler set up in an ASP.NET Core application. Profiling works fine.
However, I only want Admins to be able to profile.
I have the following in ConfigureServices
:
services.AddMiniProfiler(options =>
{
options.ShouldProfile = request =>
request.HttpContext.User.IsInRole("Admin");
});
The problem is, the user identity does not seem to be loaded in that method.
The User.Identity.Name
property is null, and there are no claims.
My guess is that this call happens before that info is populated?
How can I profile based on the user identity?
You need to know that according to the docs the ClaimsPrincipal.IsInRole()
method checks for Claims of type ClaimsIdentity.RoleClaimType
.Be sure you have added the role claims.
Here is a working demo you could follow:
1.Register the user with name a@qq.com
successfully.
2.Generate the role and add the role with claims to the user:
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();
});
}
Result: