Grzegorz Borkowski (Migrated from SEC-1159) said:

I'm trying to figure out how to add concept of "context-dependant roles", i.e. roles granted to the user only for specific domain objects. Currently you can link Access Control Entry from ACL to either specific user, or the role. But role is global here: if you have a role PROJECT_MANAGER you are the manager for all projects in the system. This is not very practical. I want to be able to say: user A is a manager for project X, but not for project Y. Being the manager for project, means that you are granted many privileges for this project: read, update, delete, add task, etc. So if user A has MANAGER role on project X, he is granted all the permissions on this project. Now suppose there can be many managers for this project. Repeating all the permission records for every manager is is pointless: I would prefer to just assign these permissions to the role MANAGER (like with GranthedAuthoritySid) but assign the role to the user not globally, but in the context of specific instance of domain object.

After thinking about it, I see the following solution for this. 1.JdbcAclService uses 4 tables in database. We'll need the 5th one, called say "ACL_ROLE_TO_PRINCIPAL". It has four columns: first is autoincrement ID, second is a foreign key to ACL_OBJECT_IDENTITY table pointing at "context object", third is a foreign key to ACL_SID tables pointing at user principal (row with principal flag set to true), i.e. to the user, and forth is again foreign key to ACL_SID pointing at role name (granted authority), ie. at row with principal flag set to false. Now if you want to say that users A,B and C are managers in project X, you create three rows in this table with following values: 1, X-ref, A-ref, MANAGER-ref 2, X-ref, B-ref, MANAGER-ref 3, X-ref, C-ref, MANAGER-ref 1. We create new interface, similar to SidRetrievalStrategyImpl, say called ObjectSpecificGrantedAuthoritiesRetrievalStrategy or so, with one method: public Sid[] getObjectSpecificSids(Sid[] globalSids, ObjectIdentity objectIdentity) Implementation of this interface will use the table mentioned above to retrieve Sids based on it. For example, for user A the "global" sid array passed to this method could contain only one element: PrinciapalSid ("A"), and the method will return the Sid array with one elment: GrantedAuthoritySid ("MANAGER").

3.The AclEntryImplementation must be refactored: the property with ObjectSpecificGrantedAuthoritiesRetrievalStrategy must be added (getter and setter). Then in the vote() method implementation (main method of the voter), after these lines (based on 2.0.4 source): // Obtain the OID applicable to the domain object ObjectIdentity objectIdentity = objectIdentityRetrievalStrategy.getObjectIdentity(domainObject);

        // Obtain the SIDs applicable to the principal
        Sid[] sids = sidRetrievalStrategy.getSids(authentication);

we would add the lines: if (objectSpecificAuthoritiesRetrievalStrategy != null) { Sid[] objectSpecificSids = objectSpecificAuthoritiesRetrievalStrategy.getObjectSpecificSids(sids, ObjectIdentity objectIdentity); sids = ...//merge sids array with objectSpecicSids }

The overall result seems very powerful and not much complicated, and would significantly enhance the ACL package capabilities.

Comment From: spring-projects-issues

Luke Taylor said:

Since the role here is object-specific, this seems similar to just adding an extra permission which includes all the others (like the "admin" permission in the contacts sample app), so I'm not sure it's worth adding an extra strategy and database table. The fact that one permission implies others can be accounted for in the PermissionGrantingStrategy.

Comment From: spring-projects-issues

Srđan Šrepfler said:

Our use case for this thing would be that in our system it's possible to define various organizations and users can have roles that are organization specific. Actions on resources related to the organizations should be constrained not only on the role but also on the context (ex. and Operator from OrganizationA might be assigned rights to access a Resource that references OrganizationB). I think this would be a really nice addition to spring security. Luke, can you elaborate or point to an example?

Comment From: spring-projects-issues

Luke Taylor said:

Could you clarify exactly how the suggested change fits your use case please? i.e. what would be the objects, sids and object identities involved?

Comment From: spring-projects-issues

Srđan Šrepfler said:

I can't comment on sids and object identities because we simply could did not find acegi supporting our use case so we added controls in the business logic (long time ago). I'll try to explain with a concrete example, let's say we have a system that manages a data for multiple companies in the same business. And let's say these companies are in the business of fixing Things. Now, if a User with the Administrator role in the CompanyA I can insert a Thing in the Company's inventory, but the other User even if he has the Administrator role cannot, because the role should have some context reference (in our case a reference to the CompanyA).

Comment From: spring-projects-issues

Luke Taylor said:

Ok, I'm still not clear whether you are actually saying that the code changes suggested here support your use case or not. If you are then you'll need to explain how.

If you are talking about some other functionality which sounds similar but isn't directly ACL-module related, then that doesn't affect whether this issue (as described here, specific to the existing ACL code) should be implemented or not (which is what I'd like to clarify at the moment).

Comment From: spring-projects-issues

Luke Taylor said:

Deferring for now.

Comment From: spring-projects-issues

Chris Cranford said:

One of the reasons we chose to bypass ACL which looked like a great candidate on the surface was because domain object permissions were not just role or user specific. For example, users are assigned an INVENTORY ROLE which grants them a set of permissions within the inventory module. These permissions are the typical CRUD permissions. However users who are granted this role aren't to be allowed to do this for every item domain object; but only certain ones that are within company code A or within organization B.

So what I believe is being requested is to have an additional way that for a specific role, there is a context specific value which in turn applies the ROLE permission for that domain object or not. In my custom implementation, I have to check for the given item domain object, is the facility the item resides is within the list of facilities which were granted permissible access for that role or business function in the system.

In other cases, one domain object's permissions are based upon the permissions of another as well. For example, a Purchase order has a header record and multiple line records. Since a PO can be drafted to a supplier with lines to be distributed to various facilities, one user may be able to view purchase orders but only be able to view lines 1 and 3 because they're sourced to their facility where-as the same PO can have all their lines viewed by another user because their view is ALL system facilities. At the role level, they both would have the same role, but the authorization and context-specific values which add an extra layer of constraint to the permissions is what drives the system.

Comment From: rwinch

If this is to be implemented it would be external of ACLs which don't typically handle arbitrary permissions. For cases like this, please implement PermissionEvaluator or AuthorizationManager directly.