You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by Apache Wiki <wi...@apache.org> on 2011/09/13 20:23:27 UTC

[Jackrabbit Wiki] Update of "AccessControl" by AlexanderKlimetschek

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Jackrabbit Wiki" for change notification.

The "AccessControl" page has been changed by AlexanderKlimetschek:
http://wiki.apache.org/jackrabbit/AccessControl?action=diff&rev1=16&rev2=17

Comment:
added sample for setting resource-based acls and more

  
  Advantages:
   * fully supported by the JCR API / specification
+  * very widely available ACL model (eg. file systems)
+  * simple resource inheritance
   * default mechanism in Jackrabbit, no configuration needed
-  * very widely available ACL model (eg. file systems)
  
  Disadvantages:
   * cannot assign ACLs to non-existent nodes
+  * cumbersome when many users need un-groupable ACLs on a few resources (e.g. "subscriptions"), lots of ACL entries per resource
   * permissions are stored right inside the content (can be cumbersome for backups, etc.)
+ 
+ === How Resource-based ACLs are stored ===
+ 
+ Resource-based ACLs are stored per resource/node in a special child node {{{rep:policy}}}. This one will have a list of {{{rep:GrantACE}}} child nodes (usually named {{{allow}}}, {{{allow0}}},...) for grant access control entries and {{{rep:DenyACE}}} child nodes (usually named {{{deny}}}, {{{deny0}}},...) for deny access control entries.
+ 
+ Each ACE node has a {{{rep:principalName}}} STRING property pointing to the user or group this ACE belongs to, and a {{{rep:privileges}}} NAME multi-value property, containing all the privileges of this ACE.
+ 
+ Note that you can read/browse these nodes using the JCR API, but cannot modify them. This must always happen through the JCR access control API.
+ 
+ === API for setting resource-based ACLs ===
+ 
+ This is an example granting all rights to everyone, using the plain JCR API:
+ {{{
+ AccessControlManager aMgr = session.getAccessControlManager();
+ 
+ // create a privilege set with jcr:all
+ Privilege[] privileges = new Privilege[] { aMgr.privilegeFromName(Privilege.JCR_ALL) };
+ AccessControlList acl;
+ try {
+     // get first applicable policy (for nodes w/o a policy)
+     acl = aMgr.getApplicablePolicies(path).nextAccessControlPolicy();
+ } catch (NoSuchElementException e) {
+     // else node already has a policy, get that one
+     acl = aMgr.getPolicies(path)[0];
+ }
+ // remove all existing entries
+ for (AccessControlEntry e : acl.getAccessControlEntries()) {
+     acl.removeAccessControlEntry(e);
+ }
+ // add a new one for the special "everyone" principal
+ acl.addAccessControlEntry(EveryonePrincipal.getInstance(), privileges, true);
+ 
+ // the policy must be re-set
+ aMgr.setPolicy(path, cal);
+ 
+ // and the session must be saved for the changes to be applied
+ session.save();
+ }}}
+ 
+ (for links and more code, see below)
+ 
+ === Difference between getPolicies() and getApplicablePolicies() ===
+ 
+ {{{AccessControlManager.getApplicablePolicies(path)}}} returns an iterator over all applicable policies that you can potentially define for that node. This depends on what the implementation provides. Jackrabbit only supports one policy, the {{{AccessControlList}}}. If this is already applied to that node (in case the node is not new) you get an empty iterator.
+ 
+ A more correct way (than the code sample above) would check if any of the policies returned by the iterator is an {{{AccessControlList}}} and use that one. If you cannot find one for a new node, then that policy is not supported by that specific JCR implementation.
+ 
+ The {{{AccessControlManager.getPolicies(path)}}} only returns the policies that are already applied (i.e. persisted and active) on that node. In case of a new node, this should be empty.
+ 
  
  == Principal-based ACLs ==
  A different approach for specifying and storing ACLs is to assign certain principals (users or groups) a list of nodes that they are allowed or denied to work on. The nodes will be referenced by paths, and might even include wildcards.
@@ -43, +94 @@

  Advantages:
   * permissions can be assigned to non-existent nodes
   * permissions are stored separately from the content (good for content replication, backup etc.)
+  * good for having many users with un-groupable ACLs (e.g. "subscriptions"); resources don't get filled up with ACL entries
  
  Disadvantages:
   * additional Jackrabbit API has to be used for setting ACLs
+  * modeling resource inheritance requires more ACLs than resource-based
  
  === How Principal-based ACLs are stored ===
  
- An access control list ({{{rep:ACL}}}) is stored for each user and group (this is transparent, currently it's mirroring the users's home path at {{{/rep:accesscontrol/<principal-path>/rep:policy/}}}). This consists of entries ({{{rep:ACE}}}), which are either allow ({{{rep:GrantACE}}}) or deny ({{{rep:GrantACE}}}) entries.
+ An access control list ({{{rep:ACL}}}) is stored for each user and group (this is transparent, currently it's mirroring the users's home path at {{{/rep:accesscontrol/<principal-path>/rep:policy/}}}). This consists of entries ({{{rep:ACE}}}), which are either allow ({{{rep:GrantACE}}}) or deny ({{{rep:DenyACE}}}) entries.
  
  The {{{rep:ACE}}} nodetype (used by both resource- and principal-based ACLs) defines the following two properties for principal-based usage. These exact same names need to be used as restrictions when using the Jackrabbit API ([[http://jackrabbit.apache.org/api/2.2/org/apache/jackrabbit/api/security/JackrabbitAccessControlList.html#addEntry(java.security.Principal,%20javax.jcr.security.Privilege[],%20boolean,%20java.util.Map)|JackrabbitAccessControlList.addEntry()]]):
  
@@ -142, +195 @@

  
  == TODO ==
  
-  * setting resource-based ACLs via the JCR API
-  * how resource-based ACLs are stored
   * AccessControlProvider as an interface to extend for custom acl
   * general security config