3.2.1.2.2. Access control system

An extended Access Control system consists of:

Access context action

SetAccessControlContextAction implements Action and may be called by SessionActionInterceptor as a reaction of some events - usually before writing methods and after reading (getNode(), getProperty(), and more). This SetAccessControlContextAction calls the AccessManager.setContext(InvocationContext context) method which sets the ThreadLocal invocation context for the current call.

Action's configuration may look like as the following:


<value>
  <object type="org.exoplatform.services.jcr.impl.ext.action.ActionConfiguration">
    <field  name="eventTypes"><string>addNode,read</string></field>
    <field  name="workspace"><string>production</string></field >
    <field  name="actionClassName"><string>org.exoplatform.services.jcr.ext.access.SetAccessControlContextAction</string></field>       
  </object>
</value>

Invocation context

The InvocationContext contains the current Item, the previous Item, the current ExoContainer and the current EventType look like below:

public class InvocationContext extends HashMap implements Context {


    /**
    * @return The related eXo container.
    */
    public final ExoContainer getContainer()
    /**
    * @return The current item.
    */
    public final Item getCurrentItem()
    /**
    * @return The previous item before the change.
    */
    public final Item getPreviousItem()
    /**
    * @return The type of the event.
    */
    public final int getEventType()
    }
  

Custom extended access manager

By default, all workspaces share an AccessManager instance, created by RepositoryService at the startup (DefaultAccessManagerImpl) which supports default access control policy as described in the Access Control section. Custom Access Control policy can be applied to certain Workspace configuring access-manager element inside workspace as follows:


<workspace name="ws">        
   ...
   <!-- after query-handler element -->
   <access-manager class="org.exoplatform.services.jcr.CustomAccessManagerImpl">
      <properties>
         <property name="someProperty" value="value"/>
         ...
      </properties>
  </access-manager>
  ...
</workspace>

When implementing AccessManager, the hasPermission() method has to be overridden so it uses the current invocation context at its discretion. For instance, it may get the current node's metadata and make a decision if the current User has appropriate permissions. Use Invocation Context's runtime properties to make a decision about current Session's privileges.

For example: The following is a simplified Sequence diagram for the Session.getNode() method:

Example of a custom access manager

The sample CustomAccessManagerImpl below extends the default access manager and uses some DecisionMakingService in the overloaded hasPermission method to find out if a current user has permission to use current item, event type, user and some parameters of AccessManager. To make this Access manager work, it is necessary to configure it in the JCR configuration as mentioned in Extended Access Manager and SetAccessControlContextAction should be configured in the way mentioned in Access Context Action.

public class CustomAccessManagerImpl extends AccessManager {


  private String property;
  private DecisionMakingService theService;
  public CustomAccessManagerImpl (RepositoryEntry config, WorkspaceEntry wsConfig,
      DecisionMakingService someService) throws RepositoryException, RepositoryConfigurationException {
    super(config, wsConfig);
    this.property = wsConfig.getAccessManager().getParameterValue("someParam");
    this.theService = someService;
  }
  @Override
  public boolean hasPermission(AccessControlList acl, String[] permission, Identity user) {
    // call the default permission check
    if (super.hasPermission(acl, permission, user)) {
      
      Item curItem = context().getCurrentItem();
      int eventType = context().getEventType();
      ExoContainer container = context().getContainer();
      // call some service's method
      return theService.makeDecision(curItem, eventType, user, property);
    } else {
      return false;
    }
  }
}
Copyright ©. All rights reserved. eXo Platform SAS
blog comments powered byDisqus