You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jackrabbit.apache.org by Ashley Martens <ma...@asconline.com> on 2007/08/22 17:46:20 UTC

AccessManager Help?

I'm trying to modify a custom AccessManager by having it check properties of the node that is being accessed. However, I can't get to the Node from the AccessManager. I know this sounds stupid but how do you give the AccessManager a Session?
 
 E-Mail Confidentiality Notification
-----------------------------------
This e-mail message (and any associated files) contains information from Associated Software Consultants (ASC), Inc. and is intended only for the use of the individual or entity to which it is addressed and may contain information that is confidential, subject to copyright or constitutes a trade secret. If you are not the intended recipient you are hereby notified that any dissemination, copying or distribution of this message, or files associated with this message, is strictly prohibited. If you have received this message in error, please notify us immediately by replying to the message and deleting it from your computer. Messages sent to and from us may be monitored.

Re: AccessManager Help?

Posted by Torgeir Veimo <to...@pobox.com>.
On Wed, 2007-08-22 at 08:46 -0700, Ashley Martens wrote:
> I'm trying to modify a custom AccessManager by having it check
> properties of the node that is being accessed. However, I can't get to
> the Node from the AccessManager. I know this sounds stupid but how do
> you give the AccessManager a Session?

Either maintain a system session for this purpose, or use a cache with
uuids as keys for those nodes that are protected. Search the mailing
list for examples.

-- 
-Tor


RE: AccessManager Help?

Posted by bilobag <bi...@hotmail.com>.
Thanks for posting your code.  However, I am wondering how you are getting
access to the repository.  You have a method called getRepositoryImpl() that
always returns null.  Is this code currently working?  Does anyone know of a
way to inject an object into an AccessManager using dependancy injection for
Spring?  I am confused about how to set objects in the AccessManager...do we
use properties in the configuration for the accessManager?  



Ashley Martens wrote:
> 
> Thanks. I really had to comb the mail list for an answer so I'm posting my
> code for others, so they don't have to beat themselves up.
> 
> import java.util.logging.Logger;
> import java.security.Principal;
> import javax.security.auth.Subject;
> import org.apache.jackrabbit.core.HierarchyManager;
> import org.apache.jackrabbit.core.ItemId;
> import org.apache.jackrabbit.core.NodeId;
> import org.apache.jackrabbit.core.PropertyId;
> import org.apache.jackrabbit.core.RepositoryImpl;
> import org.apache.jackrabbit.core.SessionImpl;
> import org.apache.jackrabbit.core.config.WorkspaceConfig;
> import org.apache.jackrabbit.core.fs.FileSystem;
> import org.apache.jackrabbit.core.security.AMContext;
> import org.apache.jackrabbit.core.security.AccessManager;
> import org.apache.jackrabbit.core.security.AnonymousPrincipal;
> import org.apache.jackrabbit.core.security.SystemPrincipal;
> import org.apache.jackrabbit.uuid.UUID;
> 
> public class MyAccessManager implements AccessManager {
>  private static final Logger LOGGER =
> Logger.getLogger(PLAccessManager.class.getName());
>  /**
>  * Subject whose access rights this AccessManager should reflect
>  */
>  protected Subject subject = null;
>  /**
>  * hierarchy manager used for ACL-based access control model
>  */
>  protected HierarchyManager hierMgr = null;
>  /**
>  */
>  protected FileSystem fs = null;
>  private javax.jcr.Session systemSession = null;
>  private Principal principal = null;
>  private boolean initialized = false;
>  protected boolean system    = false;
>  protected boolean anon      = false;
>  /**
>  * mailto:%7B@inheritDoc}
>  */
>  public void init(AMContext context) throws
> javax.jcr.AccessDeniedException, Exception {
>   if (initialized) {
>    throw new IllegalStateException("already initialized");
>   }
>   this.systemSession = new SystemSession(getRepositoryImpl(),
>                                          createSystemSubject(),
>                                         
> getWorkspaceConfig(context.getWorkspaceName()));
>   this.subject = context.getSubject();
>   this.hierMgr = context.getHierarchyManager();
>   this.fs      = context.getFileSystem();
>   this.anon    =
> !subject.getPrincipals(AnonymousPrincipal.class).isEmpty();
>   this.system  = !subject.getPrincipals(SystemPrincipal.class).isEmpty();
>   // @todo This should be changed to meet your needs
>   java.util.Set<Principal> principals =
> subject.getPrincipals(Principal.class);
>   for (Principal p : principals) {
>    this.principal = p;
>    break;
>   }
>   this.initialized = true;
>  }
>  /**
>  * mailto:%7B@inheritDoc}
>  */
>  public void close() throws Exception {
>   if (!initialized) {
>    throw new IllegalStateException("not initialized");
>   }
>   this.systemSession.logout();
>   this.systemSession = null;
>   this.subject   = null;
>   this.hierMgr   = null;
>   this.fs        = null;
>   this.principal = null;
>   this.system      = false;
>   this.anon        = false;
>   this.initialized = false;
>  }
>  /**
>  * mailto:%7B@inheritDoc}
>  */
>  public boolean canAccess(String workspaceName)
>   throws javax.jcr.NoSuchWorkspaceException, javax.jcr.RepositoryException
>  {
>   if (!initialized) {
>    throw new IllegalStateException("not initialized");
>   }
>   return this.system || this.anon || this.principal != null;
>  }
>  /**
>  * mailto:%7B@inheritDoc}
>  */
>  public void checkPermission(ItemId id, int permissions)
>   throws javax.jcr.AccessDeniedException, javax.jcr.ItemNotFoundException,
>       javax.jcr.RepositoryException
>  {
>   if (!initialized) {
>    throw new IllegalStateException("not initialized");
>   }
>   if (!isGranted(id, permissions)) {
>    throw new javax.jcr.AccessDeniedException();
>   }
>  }
>  /**
>  * mailto:%7B@inheritDoc}
>  */
>  public boolean isGranted(ItemId id, int permissions)
>   throws javax.jcr.ItemNotFoundException, javax.jcr.RepositoryException
>  {
>   boolean granted = false;
>   if (!initialized) {
>    throw new IllegalStateException("not initialized");
>   }
>   // The system user can do whatever it needs to
>   if (this.system) {
>    granted = true;
>   }
>   else if (this.anon && (permissions & this.READ) == this.READ) {
>    granted = true;
>   }
>   else if (this.principal == null) {
>    throw new IllegalStateException("No principal");
>   }
>   else {
>    NodeId nid = null;
>    UUID uuid = null;
>    if (id.denotesNode()) {
>     nid = (NodeId) id;
>    } else {
>     // It's property so get the parent node
>     PropertyId pid = (PropertyId) id;
>     nid = pid.getParentId();
>    }
>    uuid = nid.getUUID();
>    // Get the node
>    javax.jcr.Node n = this.systemSession.getNodeByUUID(uuid.toString());
>    // Compare permissions
>    if ((permissions & this.REMOVE) == this.REMOVE) {
>     // @todo Implement this
>    }
>    if ((permissions & this.WRITE) == this.WRITE)  {
>     // @todo Implement this
>    }
>    if ((permissions & this.READ) == this.READ) {
>     // @todo Implement this
>    }
>   }
>   return granted;
>  }
>  private Subject createSystemSubject() {
>   // create subject with SystemPrincipal
>   java.util.Set principals = new java.util.HashSet();
>   principals.add(new SystemPrincipal());
>   Subject subject =
>    new Subject(true, principals,
>      java.util.Collections.EMPTY_SET,
>      java.util.Collections.EMPTY_SET);
>   return subject;
>  }
>  private RepositoryImpl getRepositoryImpl() {
>   // @todo Implement this
>   return null;
>  }
>  private WorkspaceConfig getWorkspaceConfig(String workspace) {
>   RepositoryImpl ri = getRepositoryImpl();
>   WorkspaceConfig wc = ri.getConfig().getWorkspaceConfig(workspace);
>   return wc;
>  }
>  /**
>  * A system session that allows the access manager to get nodes from the
>  * repository and by-pass the login module.
>  */
>  private class SystemSession extends SessionImpl {
>   private SystemSession(RepositoryImpl ri, Subject s, WorkspaceConfig wc)
>    throws javax.jcr.RepositoryException
>   {
>    super(ri, s, wc);
>   }
>   /**
>   * mailto:%7B@inheritDoc}
>   * <p/>
>   * Overridden in order to create custom access manager
>   *
>   * @return access manager for system session
>   * @throws AccessDeniedException is never thrown
>   * @throws RepositoryException   is never thrown
>   */
>   protected AccessManager createAccessManager(Subject subject,
>      HierarchyManager hierMgr)
>    throws javax.jcr.AccessDeniedException, javax.jcr.RepositoryException
>   {
>    /*
>    * use own AccessManager implementation rather than relying on
>    * configurable AccessManager to handle SystemPrincipal privileges
>    * correctly and avoid recursive problems (AccessManager creates
>    * SystemSession which creates AccessManager)
>    */
>    return new SystemAccessManager();
>   }
>   private class SystemAccessManager implements AccessManager {
>    /**
>    * mailto:%7B@inheritDoc}
>    *
>    * @throws AccessDeniedException is never thrown
>    * @throws Exception             is never thrown
>    */
>    public void init(AMContext context)
>     throws javax.jcr.AccessDeniedException, Exception
>    {
>    }
>    /**
>    * mailto:%7B@inheritDoc}
>    */
>    public void close() throws Exception {
>    }
>    /**
>    * mailto:%7B@inheritDoc}
>    *
>    * @throws AccessDeniedException is never thrown
>    * @throws ItemNotFoundException is never thrown
>    * @throws RepositoryException   is never thrown
>    */
>    public void checkPermission(ItemId id, int permissions)
>     throws javax.jcr.AccessDeniedException,
>            javax.jcr.ItemNotFoundException,
>            javax.jcr.RepositoryException
>    {
>    }
>    /**
>    * mailto:%7B@inheritDoc}
>    *
>    * @return always <code>true</code>
>    * @throws ItemNotFoundException is never thrown
>    * @throws RepositoryException   is never thrown
>    */
>    public boolean isGranted(ItemId id, int permissions)
>     throws javax.jcr.ItemNotFoundException,
>            javax.jcr.RepositoryException
>    {
>     // allow everything
>     return true;
>    }
>    /**
>    * mailto:%7B@inheritDoc}
>    *
>    * @return always <code>true</code>
>    * @throws NoSuchWorkspaceException is never thrown
>    * @throws RepositoryException      is never thrown
>    */
>    public boolean canAccess(String workspaceName)
>     throws javax.jcr.NoSuchWorkspaceException,
>            javax.jcr.RepositoryException
>    {
>     return true;
>    }
>   }
>  }
> }
> 
> 
> 
> 
> From: Torgeir Veimo
> Sent: Wed 8/22/2007 9:06 AM
> To: dev@jackrabbit.apache.org
> Subject: Re: AccessManager Help?
> 
> 
> On Wed, 2007-08-22 at 08:46 -0700, Ashley Martens wrote:
>> I'm trying to modify a custom AccessManager by having it check
>> properties of the node that is being accessed. However, I can't get to
>> the Node from the AccessManager. I know this sounds stupid but how do
>> you give the AccessManager a Session?
> 
> Either maintain a system session for this purpose, or use a cache with
> uuids as keys for those nodes that are protected. Search the mailing
> list for examples.
> 
> -- 
> -Tor
> 
> 

-- 
View this message in context: http://www.nabble.com/AccessManager-Help--tf4312433.html#a12482016
Sent from the Jackrabbit - Dev mailing list archive at Nabble.com.


RE: AccessManager Help?

Posted by Ashley Martens <ma...@asconline.com>.
Thanks. I really had to comb the mail list for an answer so I'm posting my code for others, so they don't have to beat themselves up.

import java.util.logging.Logger;
import java.security.Principal;
import javax.security.auth.Subject;
import org.apache.jackrabbit.core.HierarchyManager;
import org.apache.jackrabbit.core.ItemId;
import org.apache.jackrabbit.core.NodeId;
import org.apache.jackrabbit.core.PropertyId;
import org.apache.jackrabbit.core.RepositoryImpl;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.config.WorkspaceConfig;
import org.apache.jackrabbit.core.fs.FileSystem;
import org.apache.jackrabbit.core.security.AMContext;
import org.apache.jackrabbit.core.security.AccessManager;
import org.apache.jackrabbit.core.security.AnonymousPrincipal;
import org.apache.jackrabbit.core.security.SystemPrincipal;
import org.apache.jackrabbit.uuid.UUID;

public class MyAccessManager implements AccessManager {
 private static final Logger LOGGER = Logger.getLogger(PLAccessManager.class.getName());
 /**
 * Subject whose access rights this AccessManager should reflect
 */
 protected Subject subject = null;
 /**
 * hierarchy manager used for ACL-based access control model
 */
 protected HierarchyManager hierMgr = null;
 /**
 */
 protected FileSystem fs = null;
 private javax.jcr.Session systemSession = null;
 private Principal principal = null;
 private boolean initialized = false;
 protected boolean system    = false;
 protected boolean anon      = false;
 /**
 * mailto:%7B@inheritDoc}
 */
 public void init(AMContext context) throws javax.jcr.AccessDeniedException, Exception {
  if (initialized) {
   throw new IllegalStateException("already initialized");
  }
  this.systemSession = new SystemSession(getRepositoryImpl(),
                                         createSystemSubject(),
                                         getWorkspaceConfig(context.getWorkspaceName()));
  this.subject = context.getSubject();
  this.hierMgr = context.getHierarchyManager();
  this.fs      = context.getFileSystem();
  this.anon    = !subject.getPrincipals(AnonymousPrincipal.class).isEmpty();
  this.system  = !subject.getPrincipals(SystemPrincipal.class).isEmpty();
  // @todo This should be changed to meet your needs
  java.util.Set<Principal> principals = subject.getPrincipals(Principal.class);
  for (Principal p : principals) {
   this.principal = p;
   break;
  }
  this.initialized = true;
 }
 /**
 * mailto:%7B@inheritDoc}
 */
 public void close() throws Exception {
  if (!initialized) {
   throw new IllegalStateException("not initialized");
  }
  this.systemSession.logout();
  this.systemSession = null;
  this.subject   = null;
  this.hierMgr   = null;
  this.fs        = null;
  this.principal = null;
  this.system      = false;
  this.anon        = false;
  this.initialized = false;
 }
 /**
 * mailto:%7B@inheritDoc}
 */
 public boolean canAccess(String workspaceName)
  throws javax.jcr.NoSuchWorkspaceException, javax.jcr.RepositoryException
 {
  if (!initialized) {
   throw new IllegalStateException("not initialized");
  }
  return this.system || this.anon || this.principal != null;
 }
 /**
 * mailto:%7B@inheritDoc}
 */
 public void checkPermission(ItemId id, int permissions)
  throws javax.jcr.AccessDeniedException, javax.jcr.ItemNotFoundException,
      javax.jcr.RepositoryException
 {
  if (!initialized) {
   throw new IllegalStateException("not initialized");
  }
  if (!isGranted(id, permissions)) {
   throw new javax.jcr.AccessDeniedException();
  }
 }
 /**
 * mailto:%7B@inheritDoc}
 */
 public boolean isGranted(ItemId id, int permissions)
  throws javax.jcr.ItemNotFoundException, javax.jcr.RepositoryException
 {
  boolean granted = false;
  if (!initialized) {
   throw new IllegalStateException("not initialized");
  }
  // The system user can do whatever it needs to
  if (this.system) {
   granted = true;
  }
  else if (this.anon && (permissions & this.READ) == this.READ) {
   granted = true;
  }
  else if (this.principal == null) {
   throw new IllegalStateException("No principal");
  }
  else {
   NodeId nid = null;
   UUID uuid = null;
   if (id.denotesNode()) {
    nid = (NodeId) id;
   } else {
    // It's property so get the parent node
    PropertyId pid = (PropertyId) id;
    nid = pid.getParentId();
   }
   uuid = nid.getUUID();
   // Get the node
   javax.jcr.Node n = this.systemSession.getNodeByUUID(uuid.toString());
   // Compare permissions
   if ((permissions & this.REMOVE) == this.REMOVE) {
    // @todo Implement this
   }
   if ((permissions & this.WRITE) == this.WRITE)  {
    // @todo Implement this
   }
   if ((permissions & this.READ) == this.READ) {
    // @todo Implement this
   }
  }
  return granted;
 }
 private Subject createSystemSubject() {
  // create subject with SystemPrincipal
  java.util.Set principals = new java.util.HashSet();
  principals.add(new SystemPrincipal());
  Subject subject =
   new Subject(true, principals,
     java.util.Collections.EMPTY_SET,
     java.util.Collections.EMPTY_SET);
  return subject;
 }
 private RepositoryImpl getRepositoryImpl() {
  // @todo Implement this
  return null;
 }
 private WorkspaceConfig getWorkspaceConfig(String workspace) {
  RepositoryImpl ri = getRepositoryImpl();
  WorkspaceConfig wc = ri.getConfig().getWorkspaceConfig(workspace);
  return wc;
 }
 /**
 * A system session that allows the access manager to get nodes from the
 * repository and by-pass the login module.
 */
 private class SystemSession extends SessionImpl {
  private SystemSession(RepositoryImpl ri, Subject s, WorkspaceConfig wc)
   throws javax.jcr.RepositoryException
  {
   super(ri, s, wc);
  }
  /**
  * mailto:%7B@inheritDoc}
  * <p/>
  * Overridden in order to create custom access manager
  *
  * @return access manager for system session
  * @throws AccessDeniedException is never thrown
  * @throws RepositoryException   is never thrown
  */
  protected AccessManager createAccessManager(Subject subject,
     HierarchyManager hierMgr)
   throws javax.jcr.AccessDeniedException, javax.jcr.RepositoryException
  {
   /*
   * use own AccessManager implementation rather than relying on
   * configurable AccessManager to handle SystemPrincipal privileges
   * correctly and avoid recursive problems (AccessManager creates
   * SystemSession which creates AccessManager)
   */
   return new SystemAccessManager();
  }
  private class SystemAccessManager implements AccessManager {
   /**
   * mailto:%7B@inheritDoc}
   *
   * @throws AccessDeniedException is never thrown
   * @throws Exception             is never thrown
   */
   public void init(AMContext context)
    throws javax.jcr.AccessDeniedException, Exception
   {
   }
   /**
   * mailto:%7B@inheritDoc}
   */
   public void close() throws Exception {
   }
   /**
   * mailto:%7B@inheritDoc}
   *
   * @throws AccessDeniedException is never thrown
   * @throws ItemNotFoundException is never thrown
   * @throws RepositoryException   is never thrown
   */
   public void checkPermission(ItemId id, int permissions)
    throws javax.jcr.AccessDeniedException,
           javax.jcr.ItemNotFoundException,
           javax.jcr.RepositoryException
   {
   }
   /**
   * mailto:%7B@inheritDoc}
   *
   * @return always <code>true</code>
   * @throws ItemNotFoundException is never thrown
   * @throws RepositoryException   is never thrown
   */
   public boolean isGranted(ItemId id, int permissions)
    throws javax.jcr.ItemNotFoundException,
           javax.jcr.RepositoryException
   {
    // allow everything
    return true;
   }
   /**
   * mailto:%7B@inheritDoc}
   *
   * @return always <code>true</code>
   * @throws NoSuchWorkspaceException is never thrown
   * @throws RepositoryException      is never thrown
   */
   public boolean canAccess(String workspaceName)
    throws javax.jcr.NoSuchWorkspaceException,
           javax.jcr.RepositoryException
   {
    return true;
   }
  }
 }
}




From: Torgeir Veimo
Sent: Wed 8/22/2007 9:06 AM
To: dev@jackrabbit.apache.org
Subject: Re: AccessManager Help?


On Wed, 2007-08-22 at 08:46 -0700, Ashley Martens wrote:
> I'm trying to modify a custom AccessManager by having it check
> properties of the node that is being accessed. However, I can't get to
> the Node from the AccessManager. I know this sounds stupid but how do
> you give the AccessManager a Session?

Either maintain a system session for this purpose, or use a cache with
uuids as keys for those nodes that are protected. Search the mailing
list for examples.

-- 
-Tor