Base solution for your next web application
Open Closed

Role permission changes not propagating to users #12658


User avatar
0
KieranIrl created

Hello, we are running ASP.NET Zero 9.1.3 (ABP Framework, .NET 8, Angular 13) with Redis caching across multiple app server nodes (~5000 users).

When an admin modifies a role's permissions via RoleAppService → AbpRoleManager.SetGrantedPermissionsAsync(), the AbpRolePermissionCacheItemInvalidator correctly evicts the AbpZeroRolePermissions cache entry for that role.

However, the affected users do not see their new effective permissions for hours. We have identified two gaps:

  1. Server-side: The AbpUserPermissionCacheItemInvalidator does not listen for EntityChangedEventData<RolePermissionSetting>, but we believe this is by design since the user cache only stores role IDs and user-specific overrides, and the permission checker resolves role permissions from the role cache at check time. Can you confirm the server-side resolution is immediately correct after role cache invalidation?
  2. Client-side: The Angular app fetches abp.auth.grantedPermissions once at boot via /AbpUserConfiguration/GetAll and never refreshes. The user's JWT security stamp is not changed when role permissions are modified, so no 401 is triggered and no token refresh occurs.

Our proposed fix is to update the security stamp for all users holding the modified role after SetGrantedPermissionsAsync, and trigger a location.reload() after successful token refresh on the client.

Questions:

  1. Is this the recommended approach, or does ABP/ASP.NET Zero have a built-in mechanism we're missing?
  2. Has this been addressed in newer versions of ASP.NET Zero?
  3. Is there a lighter-weight client-side mechanism?

Thank you.

Markdown is supported
Copy & paste or drag & drop images (max 30 MB per image)

2 Answer(s)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @KieranIrl

    Thanks for the detailed analysis. Your understanding is correct.

    On the server side, role permission changes should be effective immediately after the role permission cache entry is invalidated and the unit of work is completed. AbpZeroUserPermissions stores the user’s role ids and user specific granted/prohibited permissions. During permission checks, ABP checks user specific permissions first, then resolves each role through AbpRoleManager, which uses the AbpZeroRolePermissions cache. So invalidating the role permission cache is enough for server side authorization decisions.

    The stale part is the Angular client. ASP.NET Zero’s Angular application loads abp.auth.grantedPermissions from /AbpUserConfiguration/GetAll during bootstrap and uses that in PermissionCheckerService. There is no built in push/refresh mechanism that automatically reloads this client side permission snapshot when role permissions are changed.

    Updating the security stamp for all affected users can be used as a forced refresh strategy, but it is not a built in/recommended default mechanism for role permission changes. If you choose this approach, please be careful about these points:

    • Also update or remove the JWT security stamp cache entry. Otherwise an old access token may still validate against the cached old stamp.
    • Include users who receive the role through Organization Units, not only direct UserRole assignments.
    • Depending on your ASP.NET Zero version/custom JWT implementation, refresh tokens may also validate the security stamp. In that case changing the stamp may log users out instead of silently refreshing their access token.
    • For large roles, expect many users to refresh/reload at the same time, so consider a small client side delay/backoff. A lighter approach is usually to notify affected clients and refresh the client configuration instead of invalidating authentication sessions. For example, after the role permission update is committed, send a SignalR/notification event to affected users and let the Angular client either:
    • reload the page, which is the safest/simple implementation, or
    • call /AbpUserConfiguration/GetAll again and merge the new auth.grantedPermissions into the global abp object, then refresh menus/routes as needed.

    A full reload is heavier but more reliable because many parts of the Angular UI are initialized from the boot time user configuration. Re fetching only abp.auth.grantedPermissions is possible, but you need to make sure menus, route guards and already rendered permission based UI are recalculated.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    KieranIrl created

    Thank you for your reply. We've implemented the lighter approach you described.

    We've tested the fix locally with Redis and confirmed permissions propagate within the polling interval (opting for 5min) with no logout or disruption.

    One follow-up question: we are in the process of upgrading our framework. Do you think we will need additional work around this area?

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)