You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltaspike.apache.org by Shane Bryzak <sb...@redhat.com> on 2012/03/11 23:36:49 UTC

[DISCUSS] DELTASPIKE-79 Authorization API - Permissions

The Authorization API is used to enforce security restrictions on 
application resources based on the privileges assigned to the user.  I'd 
like to outline my ideas in this area below and hopefully kickstart a 
discussion.

The entry point for the Permissions API is the Identity bean, which 
exposes the following method:

boolean hasPermission(Object resource, String permission);

Here's a simple use case demonstrating how this method could be used in 
a real application:

@Inject Identity identity;
@Inject EntityManager em;
private Customer customer;

public void editCustomer(Long id)
{
     Customer c = em.find(id);
     if (!identity.hasPermission(c, "EDIT"))
     {
         throw new AuthorizationException("User does not have necessary 
privileges to edit this customer");
     }
     customer = c;
}

The Identity bean implementation of hasPermission() does very little 
work itself, it simply delegates the permission check to a 
PermissionMapper bean:

public boolean hasPermission(resource, permission)
{
      return permissionMapper.resolvePermission(resource, permission);
}

PermissionMapper is an application-scoped bean, that maintains a list of 
PermissionResolver instances.  The PermissionResolver interface defines 
the following method:

public interface PermissionResolver
{
     boolean hasPermission(Object resource, String permission);
}

When the PermissionMapper.resolvePermission() method is invoked, it 
simply iterates through its list of available PermissionResolvers, 
invoking the hasPermission() method on each one.  If any one of them 
returns a result of true, then the permission check is successful.  The 
PermissionMapper can be implemented so that PermissionResolvers that 
successfully grant permission for a particular class of resource can be 
invoked first for subsequent permission checks for the same class of 
resource, to improve performance.

I propose that we provide one PermissionResolver implementation 
(PersistentPermissionResolver, I'll get to it in a moment) with 
DeltaSpike itself, and leave it up to the user if they wish to implement 
others.  It is also trivial to provide PermissionResolver 
implementations from another library, for example we offered rule-based 
security in Seam which was built on top of the Drools rules engine.  The 
Permission API makes it simple to extend by adding new permission resolvers.

PersistentPermissionResolver is a PermissionResolver implementation that 
can be used to read resource permissions from persistent storage, such 
as a database.  It allows ACL-style permissions to be granted for 
individual resources within the domain of the application, to particular 
users, groups or roles.  Management of these permissions is performed 
through a PermissionManager bean, which declares the following methods:

public interface PermissionManager
{
     List<Permission> listGrants(Object resource, String permission);

     List<Permission> listGrants(Object resource);

     boolean grantPermission(Permission permission);more

     boolean grantPermissions(List<Permission> permissions);

     boolean revokePermission(Permission permission);

     boolean revokePermissions(List<Permission> permissions);

     List<String> listAvailablePermissions(Object resource);

     void clearPermissions(Object resource);
}

A Permission object is a simple JavaBean that represents a permission:

public interface Permission
{
     Object getResource();

     String getPermission();

     public User getUser();
}

We can go into finer detail about the storage mechanisms for persistent 
permissions later, however I'll wrap up this part of the proposal here 
as I think there's more than enough to digest.  I'd like to hear any 
thoughts or ideas about permissions or the authorization API in general.