- 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)
-
0
Any update on this?
-
0
Hi, can we get any update on this?
-
0
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. -
0
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.
-
0
hi
logout and re-login will not invalidate the
Permission
cache. You should clear thePermissionGrantCacheItem
cache from Redis after changing permission in the database. -
0
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.
-
0
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.
-
0
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?
-
0
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 byPermissionGrantCacheItem.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
-
0
public class PermissionGrantCacheItemInvalidator : Volo.Abp.PermissionManagement.PermissionGrantCacheItemInvalidator { protected ITenantStore TenantStore { get; set; }
public PermissionGrantCacheItemInvalidator(IDistributedCache<PermissionGrantCacheItem> cache, ICurrentTenant currentTenant, ITenantStore tenantStore) : base(cache, currentTenant) { TenantStore = tenantStore; } 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); } } } 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?
-
0
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.
-
0
We are changing the permissions from UI only, but there as well we need to clear redia cache and then only it reflets.
-
0
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.
-
0
in short we want to remove the role from the cache of all tenants having the role which was updated.
-
0
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 thepermission name
eventData.Entity.ProviderName
is theR
eventData.Entity.ProviderKey
is therole 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); } } }