Open Closed

Permissions taking too much time to reflect in the Application #8099


User avatar
0
pvala created
  • ABP Framework version: v8.2.1
  • UI Type: Angular
  • Database System: EF Core (MySQL)
  • Tiered (for MVC) or Auth Server Separated (for Angular): Auth Server separated
  • Exception message and full stack trace:
  • Steps to reproduce the issue:

We are facing an issue in the permissions module of the application. Actually when we add or remove any permission(s) from the AbpPermissionGrants table, by manually updating the table from the database. It takes too much time to reflect on the UI of the application. I am aware that it's getting derived via a caching mechanism but, can I know what should I do in order to make the changes instantly reflected on the UI after updating the permissions manually from the database.


15 Answer(s)
  • User Avatar
    0
    smansuri created

    Any update on this?

  • User Avatar
    0
    pvala created

    Hi, can we get any update on this?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    can I know what should I do in order to make the changes instantly reflected on the UI after updating the permissions manually from the database.

    You'd better not do this. Always do it through code.

    The framework will use IDistributedCache<PermissionGrantCacheItem> to cache the permission grants.

    AbsoluteExpiration and SlidingExpiration) used when you don't specify the options while saving cache items. Default value uses the SlidingExpiration as 20 minutes.

    https://abp.io/docs/latest/framework/fundamentals/caching#abpdistributedcacheoptions

    You can clear the PermissionGrantCacheItem cache from redis.

  • User Avatar
    0
    smansuri created

    hi

    can I know what should I do in order to make the changes instantly reflected on the UI after updating the permissions manually from the database.

    You'd better not do this. Always do it through code.

    The framework will use IDistributedCache<PermissionGrantCacheItem> to cache the permission grants.

    AbsoluteExpiration and SlidingExpiration) used when you don't specify the options while saving cache items. Default value uses the SlidingExpiration as 20 minutes.

    https://abp.io/docs/latest/framework/fundamentals/caching#abpdistributedcacheoptions

    You can clear the PermissionGrantCacheItem cache from redis.

    Even if we do populate permission through Database ,logout and relogin should repopulate the permissions correctly. isn't it? user does not have to wait for 20 minutes. moreover we have seen that the permissions to take affect take more than 2 hours at times.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    logout and re-login will not invalidate the Permission cache. You should clear the PermissionGrantCacheItem cache from Redis after changing permission in the database.

  • User Avatar
    0
    smansuri created

    This does not sound right as in real word application once you change add/remove permission from existing user through application UI should reflect immediately. For example i want to delete block the user from using the application with immediate effect or remove/add a role/permission. in this case at least on re-login the changes should take effect.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    you change add/remove permission from existing user through application UI should reflect immediately.

    Through app UI will work. But you are changing the permission directly in the database.

  • User Avatar
    0
    smansuri created

    you change add/remove permission from existing user through application UI should reflect immediately.

    Through app UI will work. But you are changing the permission directly in the database.

    Can you help us with location in identity service and/or administration service where and how abp is maintaining the permission cache for add , update and remove?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    There is no such API.

    You can add an API/Controller/endpoint to clear the cache after changing it in the database.

    Inject IDistributedCache<PermissionGrantCacheItem> Cache and remove the cache. Cache key can be calculated by PermissionGrantCacheItem.CalculateCacheKey

    eg: https://github.com/abpframework/abp/blob/rel-9.0/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionGrantCacheItemInvalidator.cs#L23-L41

  • User Avatar
    0
    pvala created

    public class PermissionGrantCacheItemInvalidator : Volo.Abp.PermissionManagement.PermissionGrantCacheItemInvalidator { protected ITenantStore TenantStore { get; set; }

    public PermissionGrantCacheItemInvalidator(IDistributedCache&lt;PermissionGrantCacheItem&gt; cache, ICurrentTenant currentTenant, ITenantStore tenantStore)
        : base(cache, currentTenant)
    {
        TenantStore = tenantStore;
    }
    
    public override async Task HandleEventAsync(EntityChangedEventData&lt;PermissionGrant&gt; eventData)
    {
        var cacheKey = CalculateCacheKey(
            eventData.Entity.Name,
            eventData.Entity.ProviderName,
            eventData.Entity.ProviderKey
        );
    
        var tenants = await TenantStore.GetListAsync();
    
        foreach (var tenant in tenants)
        {
            using (CurrentTenant.Change(tenant.Id))
            {
                await Cache.RemoveAsync(cacheKey, considerUow: true);
            }
        }
    }
    
    protected override string CalculateCacheKey(string name, string providerName, string providerKey)
    {
        return PermissionGrantCacheItem.CalculateCacheKey(name, providerName, providerKey);
    }
    

    }

    I added this file in the domain project of the AdministrationService. Here, because all the tenants will use the roles from the host tenant only, that's why if we update the permission of a role from host, it should reflect in all the tenants which are using that role. After adding this file, I ran the solution, and logged in as a user of a tenant and gave it a role from the host, now if I update the permissions of that role from the host and clear the redis cache, and refresh the page where I am logged in as a tenant user, it immediately reflects al the permissions as updated. But only after we clear redis cache. Any solution for thsi?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    I'm a little confused. Do you change the permissions from the UI page(via code) or directly in the database?

    If you change the permission from the UI page, the framework will clear the cache automatically, which means you don't need the extra code.

  • User Avatar
    0
    pvala created

    We are changing the permissions from UI only, but there as well we need to clear redia cache and then only it reflets.

  • User Avatar
    0
    pvala created

    https://abp.io/support/questions/7882/Override-the-existing-Users-Roles--Permissions-Methodology

    Here is the earlier ticket we raised to order to override and configure the role assignment fo users. Now we such a system where the roles can be only created from the host and the tenants can't create any new role, but they can use the roles which are created from the host. Now what we want is that when we update the permissions of a role, and if that role is assigned to a user in a tenant, it should immediately reflect the updated permissions for that tenant user.

  • User Avatar
    0
    smansuri created

    in short we want to remove the role from the cache of all tenants having the role which was updated.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Now what we want is that when we update the permissions of a role, and if that role is assigned to a user in a tenant, it should immediately reflect the updated permissions for that tenant user.

    I think these codes should works

    eventData.Entity.Name is the permission name eventData.Entity.ProviderName is the R eventData.Entity.ProviderKey is the role name

    You can get all permission names and remove them.

    foreach(var permissionName in permissionNames)
    {
         var cacheKey = CalculateCacheKey(
                permissionName,
                eventData.Entity.ProviderName, // R
                eventData.Entity.ProviderKey // role name
            );
    }
    
    public override async Task HandleEventAsync(EntityChangedEventData<PermissionGrant> eventData)
    {
        var cacheKey = CalculateCacheKey(
            eventData.Entity.Name,
            eventData.Entity.ProviderName,
            eventData.Entity.ProviderKey
        );
    
        var tenants = await TenantStore.GetListAsync();
    
        foreach (var tenant in tenants)
        {
            using (CurrentTenant.Change(tenant.Id))
            {
                await Cache.RemoveAsync(cacheKey, considerUow: true);
            }
        }
    }
    
Made with ❤️ on ABP v9.1.0-preview. Updated on December 10, 2024, 06:38