Open Closed

Toolbar buttons causing check permission spam on several pages #10292


User avatar
0
bmulinari created

There seems to be a bug in the way permissions are checked on toolbar buttons when the required policy is specified in the AddButton method, where we will get a spam of unnecessarily permissions checks on every minimal interaction with the page, like on every key press, for instance.

  • Steps to reproduce the issue:
  • While in debug mode, navigate to Administration -> Identity management -> Users (just an example, this seems to occur on any page with toolbar buttons)
  • Click New User or Edit on an existing user and start typing in any field
  • Verify in the console output that for every character typed a set of permission checks happen:
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Import
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Import
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Import
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Import
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Export
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Export
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Export
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Export
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Create
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Create
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Create
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Create
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Import
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Import
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Import
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Import
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Export
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Export
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Export
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Export
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Create
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Create
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Create
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Create
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Import
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Import
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Import
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Import
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Export
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Export
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Export
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Export
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Create
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Create
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Create
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Create
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Import
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Import
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Import
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Import
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Export
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Export
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Export
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Export
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Create
[15:26:29 DBG] Found in the cache: pn:U,pk:3a1beb3d-8133-1e8d-48ee-2869932f2b57,n:AbpIdentity.Users.Create
[15:26:29 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:AbpIdentity.Users.Create
[15:26:29 DBG] Found in the cache: pn:R,pk:admin,n:AbpIdentity.Users.Create
[15:26:32 DBG] Get dynamic claims cache for user: 3a1beb3d-8133-1e8d-48ee-2869932f2b57
  • Workaround we found for our own custom pages:

Default implementation where we observe the problem above, with the required permissions being specified as a parameter of the AddButton method:

private ValueTask SetToolbarItemsAsync()
{
    Toolbar.AddButton(L["Page:Button:ButtonA"],
        async () =>
        {
            await SomeActionAsync();
        },
        IconName.Sync,
        Blazorise.Color.Primary,
        requiredPolicyName: MyPermissions.MyPage.Default);

    Toolbar.AddButton(L["Page:Button:ButtonB"],
        async () =>
        {
            await SomeOtherActionAsync();
        },
        IconName.Download,
        Blazorise.Color.Secondary,
        requiredPolicyName: MyPermissions.MyPage.Default);

    return ValueTask.CompletedTask;
}

As a workaround, when we wrap the permission check around the AddButton method while removing it as a parameter, we no longer observe the permission check spam:

private async ValueTask SetToolbarItemsAsync()
{
    if (await PermissionChecker.IsGrantedAsync(MyPermissions.MyPage.Default))
    {
        Toolbar.AddButton(L["Page:Button:ButtonA"],
            async () =>
            {
                await SomeActionAsync();
            },
            IconName.Sync,
            Color.Primary);
        Toolbar.AddButton(L["Page:Button:ButtonB"],
            async () =>
            {
                await SomeOtherActionAsync();
            },
            IconName.Download,
            Color.Secondary);
    }
}

No answer yet!
Learn More, Pay Less
33% OFF
All Trainings!
Get Your Deal
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.2.0-preview. Updated on January 09, 2026, 07:22
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.