Hello,
I am currently evaluating ABP Commercial for a MVP I am building for my client:-
The client has a legacy system in PHP to manage tenancy, where each tenant has Customers and vendors. There are hardcoded filters for the isolation of objects, below is from client PHP application:-
if ($user.role->isCustomer() || $order->user_id === $user->id) {
// Grant access to edit the order
}
if ($user->hasRole('Vendor') && $user->user_id === $user->id) {
// Grant access to the Vendor belong to the vendor
}
I have reviewed ABP resource-based authorisation and wondering how I can apply the above logic with filter operators via UI instead of hardcoding, below does not give the option to use filter operators:-
// Resource-based permissions
context.AddResourcePermission(
name: BookStorePermissions.Books.Resources.View,
resourceName: BookStorePermissions.Books.Resources.Name,
managementPermissionName: BookStorePermissions.Books.ManagePermissions,
displayName: L("Permission:Books:View")
);
I want to build something like this for each object in the application:-
Thanks, Pooja
4 Answer(s)
-
0
ABP’s resource-based authorization does not support “filter operators/conditions configured from UI” (e.g.,
Order.UserId == CurrentUser.IdorVendor.UserId == CurrentUser.Id) as part of the built-in permission management UI.- The built-in UI for resource-based authorization is for granting permissions to specific resource instances (per record) to users/roles/clients, not for defining predicate/DSL-style rules.
For your legacy rules (ownership / “self” access) you should implement them with code-enforced policies, typically in one of these ABP-native ways:
Tenant isolation (already built-in)
- Ensure your entities implement
IMultiTenant(or otherwise haveTenantId) so ABP automatically isolates data per tenant.
- Ensure your entities implement
Ownership / “self” access (recommended: data filter + app service checks)
- Model ownership explicitly (e.g.,
Order.CreatorIdorOrder.CustomerUserId,Vendor.OwnerUserId). - Enforce with:
AuthorizationService.CheckAsync(resource, permissionName)only if you are using per-record grants, OR- Plain application service checks (e.g., compare entity’s owner id with
CurrentUser.Id) for “self-service” rules.
- If you want this enforced at query level (so users only see their own rows), implement a custom filtering approach (commonly done by applying
Where(...)based onCurrentUser.Idin repositories/app services). ABP’s built-in “data filters” are designed around known filter concepts (like multi-tenancy/soft-delete), not an end-user-configurable query builder for arbitrary entities.
- Model ownership explicitly (e.g.,
If you truly need a UI like your screenshot (a rule builder)
- That is a custom feature you need to build (store rules in DB, build UI, parse/evaluate rules, translate them into LINQ/SQL, and enforce them consistently).
- ABP does not ship an out-of-the-box “authorization rule query builder UI” that plugs into permissions.
If your goal is “Customer can edit only their own orders” and “Vendor can access only their own vendor profile”, the clean ABP approach is:
- Keep permissions coarse (e.g.,
Orders.Edit,Vendors.ViewSelf) - Enforce ownership constraints in the corresponding application service methods (or a domain service), e.g.:
- Load entity
- Check permission
- Check
entity.UserId == CurrentUser.Id(and tenant is already isolated)
- Keep permissions coarse (e.g.,
Sources (verified):
- https://abp.io/docs/10.4/framework/fundamentals/authorization/resource-based-authorization
- https://abp.io/docs/latest/framework/fundamentals/authorization/resource-based-authorization
- https://abp.io/docs/latest/framework/fundamentals/authorization
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi Pooja,
Thanks for the detailed write-up. One clarification first, because it changes the answer:
Are you configuring these rules at design time (you, as the developer, once per entity), or at runtime (a tenant admin builds/edits rules from a UI like the screenshot)?
The screenshot looks like a runtime rule builder, but "I want to build something like this for each object" sounds more design-time. Both paths below.
About
AddResourcePermission(...)That API isn't the right tool here. ABP's resource-based authorization is for per-record grants ("user X is allowed to edit this specific order"), stored in
AbpPermissionGrantsand checked viaIAuthorizationService.AuthorizeAsync(resource, policyName). There's no operator field because it's a per-row ACL, not a rule DSL.Your PHP rules (
$order->user_id === $user->id) aren't per-record grants — they're ownership checks, which is a different mechanism.Design-time approach (recommended for the MVP)
Your PHP rules collapse into two concerns ABP already handles centrally:
1. Tenant isolation — implement
IMultiTenanton your entities; ABP auto-filters every query byTenantId, noWhere(x => x.TenantId == ...)anywhere.2. Ownership ("self") rules — add
CreatorId(already onFullAuditedEntity) or a domain field likeCustomerUserId/VendorUserId, then enforce it once in the application service:public async Task UpdateAsync(Guid id, UpdateOrderDto input) { var order = await _orderRepository.GetAsync(id); if (!await AuthorizationService.IsGrantedAsync(MyPermissions.Orders.Manage) && order.CustomerUserId != CurrentUser.GetId()) { throw new AbpAuthorizationException(); } // update order... }That single check replaces your PHP
if. The rule lives in one place, which is the centralization you actually wanted — the PHP pain wasn't "hardcoding", it was rules scattered across controllers/views/models.For list endpoints, filter at query level so users don't even see other people's rows:
var query = await _orderRepository.GetQueryableAsync(); if (!await AuthorizationService.IsGrantedAsync(MyPermissions.Orders.Manage)) { query = query.Where(x => x.CustomerUserId == CurrentUser.GetId()); }Runtime rule-builder UI (if you really need it)
ABP doesn't ship one, and nothing in the framework (Settings, Features, SaaS, resource-based authorization) can be repurposed for it. If you must have it, you'd build the full stack yourself:
- JSON schema to store rules per entity in DB
- Querybuilder UI (jQuery QueryBuilder / react-querybuilder / etc.)
- Backend translator that compiles saved rules into
Expression<Func<T, bool>> - Hook to apply those expressions in repositories / app services
That's significant custom work — worth doing only if rules genuinely need to change without a code deploy. For an MVP I'd start with the design-time approach and only escalate if a real customer asks for runtime configuration.
Let me know which scenario you're on and I can go deeper.
Thanks,
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Thanks for your reply. I will be going by the design time approach, as there are fewer chances of error
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
