Announcement Announcement Module
No announcement yet.
ACL implementation question Page Title Module
Move Remove Collapse
This topic is closed
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • ACL implementation question

    I am in a bit of a confusion and would like to get some comments on the following issue.

    We are using ACL to protect access to a Core domain object, Lets call CostCenter, acl permissions are set according who can access which CostCenter. All works great. Now there are other domain objects like eployees, who belong to some CostCenter. I want to get only the users from the CostCentera logged in user has access to .

    My costcenter service has methods like getCostCenters which is procted by a role and return a collection of CostCenters and are filtered through acl permissions. But Employee is not an ACL Object so getEmployees() turn collection of all emplyees.

    One option was to call getCostCenters() first get a filtered list and then for each cost center get its employees. This works except getCostCenters and getEmployees have different role associated with them. So someone with getEmployees role might not be able to call getCostCenter....

    In order to solve that i have to create dummy methods like, getCostCentersTo getEmployees() and set its access differnet from getEmployees()...

    It works but doensn't feel right. Is there a better alternative?



  • #2
    Any one????


    • #3
      I'd make a separate EmployeeService and use ACL filtering on the getEmployeesForCostCentre(CostCentre) method. Then use ACL inheritence so that an Employee is a child of its CostCentre.


      • #4
        thanks Ben. Can i implement ACL inheritence for two non-parent-child domain objects. In other words Employee is not a child of CostCentre domain object but I can implement the ACL inheritence that way?


        • #5
          The inheritance hierarchy defined by the ACLs does NOT need to correlate to the inheritance hierarchy used at a class level.


          • #6
            Changing the semantics of the ACL a little bit here

            I think the semantics of either ACL or ROLES in Acegi is something the developer can make fit it needs. It is not a one size fits all thing.

            What I am saying is we can define an ACL value that means something to us. And based on that contract we can proceed further on.

            When we first faced the ACL concept in Acegi we thought, ok, let's say who can READ this Cost Center, and give that ACL value something like 2 power 2. (i am not using standard ACL values for READ/WRITE in this example).

            It ended up with user John having an acl value of 4 assigned to CostCenter A which means in our "contract" that John can read object CostCenterA.

            Then, we, configuring a BasicAclEntryAfterInvocationCollectionFilteringPro vider we were able to get a CostCenter collection with just the elements the cost centers, the authenticated user has, let's say READ access. So far so good, plain Acegi ACL stuff.

            Now, there is a service method that get all records in all cost centers. But the business requirement says we must define a privilege and enforce a filtering artifact to just return all Record objects in those Cost Centers the authenticated user has access. I am aware this might be resolved in the business domain and the achitectural discussion can just start s here. But this is what we've done.

            We created a new ACL value, let's say 2 power 4 that, in our contract means: Authenticated User having this ACL value in this Cost Center can access Records in the given Cost Center. See, the semantics is unique, is just our protocol, and our contract. And we assign this ACL entries to the user in the main object the CostCenter (no acl at the Record object level).

            We'd implemented an AfterInvocationProvider, quite similar to BasicAclEntryAfterInvocationCollectionFilteringPro vider but instead of receiving a collection of CostCenters to filter them out, it receives a Collection of records, and since every record is aware of what cost center it is in, we have all elements in there to check if the authenticated user has the right ACL entry to let the record stay in the collection. We'd configured this new after invocation filter as a regular AFTER_ACL_COLLECTION_READ and configured the service method patterns in the security context accordingly.

            Back to the architectural discussion, I am fully aware this might not be something everybody would agree. Let's see some caveats.

            -If security is enforced and filtering after collections is enabled, we are changing the returned values of a service method in our business facade. In other words, we are affecting the behaviour of a method, from the outside world (remember this is interception). The opposite is also true, if we disable collection filtering, the service would return all objects, what is not what the original requirement says. Integration test would need to consider security settings at the time they are run. Very interesting but probably off topic by now.

            -Performance. Yes, every element in a returned collection requires a trip to the ACL subsystem to see if the authenticated user has a valid ACL for every element in the collection. Well this is a price we pay for this kind of stuff.

            Some pro's. Filtering based on security settings is decoupled from business services and/or facades. Some people like this, some other do not.



            • #7
              You could create a MethodInterceptor that filters the invalid elements in the returned collection.


              • #8
                Originally posted by Ben Alex
                I'd make a separate EmployeeService and use ACL filtering on the getEmployeesForCostCentre(CostCentre) method. Then use ACL inheritence so that an Employee is a child of its CostCentre.
                Here, I understand that making Employee a child of CostCenter will resolve the problem with getAllEmployees() method and will return only employees from costcenter on which the current-user has access to (assuming AFTER_ACL_COLLECTIOn_FILTER) is applied to getAllEmployees().

                I dont understand why he needs EmployeeService.getEmployeesForCostCenter(CostCent er cc) though. Doesn't that method first require user to call getAllCostCenter() to get filtered list of CostCenters ...