Open Closed

Isolation by filter operator within a Tenancy for Customer and Vendor #10672


User avatar
0
Pooja@hotmail.com.au created

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

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

4 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    • ABP’s resource-based authorization does not support “filter operators/conditions configured from UI” (e.g., Order.UserId == CurrentUser.Id or Vendor.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:

      1. Tenant isolation (already built-in)

        • Ensure your entities implement IMultiTenant (or otherwise have TenantId) so ABP automatically isolates data per tenant.
      2. Ownership / “self” access (recommended: data filter + app service checks)

        • Model ownership explicitly (e.g., Order.CreatorId or Order.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 on CurrentUser.Id in 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.
      3. 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)

    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)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    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 AbpPermissionGrants and checked via IAuthorizationService.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 IMultiTenant on your entities; ABP auto-filters every query by TenantId, no Where(x => x.TenantId == ...) anywhere.

    2. Ownership ("self") rules — add CreatorId (already on FullAuditedEntity) or a domain field like CustomerUserId / 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)
  • User Avatar
    0
    Pooja@hotmail.com.au created

    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)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    ok If you run into any problems, feel free to contact us anytime.

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on September 16, 2026, 14:50
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.