deltaspike-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Shane Bryzak <>
Subject [DISCUSS] DELTASPIKE-79 Authorization API
Date Tue, 17 Apr 2012 22:52:58 GMT
I'd like to kick off a discussion around the Authorization API, 
specifically object permissions.  This API is used to determine whether 
the currently authenticated user has the necessary privileges to perform 
an operation on a particular domain object.  I'll start by outlining my 
proposal covering the simple use cases of this API and we can then 
proceed from there.

First of all, the developer needs a gateway into the permission API so 
that they can perform permission checks within their own application.  
This is provided by the hasPermission() method:

Identity.hasPermission(Object resource, String operation)

A permission has three aspects; 1) The application resource for which 
the permission is granted, 2) The operation that has been granted for 
that resource, and 3) The recipient of the permission, which may be 
either a User, Group or Role.

For example, if we wish to check whether the user has permission to edit 
a Customer instance the code might look like this:

@Inject Identity identity;

public void editCustomer(Customer customer)
     if (!identity.hasPermission(customer, "EDIT"))
         throw new AuthorizationException("Insufficient privileges to 
edit this customer");

     // snip code

We could potentially also do some clever stuff with method-level 
annotations here.  Off the top of my head, something like this might work:

public void editCustomer(@CheckPermission("EDIT") Customer customer)

The @CheckPermissions annotation would be a security binding type with a 
matching authorizer that would scan the parameter list and perform any 
checks on parameters annotated with @CheckPermission.  Anyway we can 
refine this idea in ongoing discussions.

In the default implementation, the Identity.hasPermission() method 
essentially contains no code, instead it delegates the permission check 
to the PermissionMapper bean, an implementation-only bean which contains 
a list of PermissionResolver instances that are used to perform the 
permission check.

public class DefaultIdentity implements Identity
     // snip code

     public boolean hasPermission(Object resource, String operation)
         return permissionMapper.resolvePermission(resource, operation);

The PermissionMapper bean provides the resolvePermission() method, which 
basically iterates through the known PermissionResolvers, and if one of 
them returns true for the permission check, then a true result is returned.

public class PermissionMapper
     @Inject Instance<PermissionResolver> resolvers;

     public boolean resolvePermission(Object resource, String operation)
         for (PermissionResolver resolver : resolvers)
             if (resolver.hasPermission(resource, operation)) return true;
         return false;

We can do some clever stuff here, like caching which permission resolver 
returns a true result for a particular class of resource, and then 
always using that resolver for that class, etc.

PermissionResolver is an API interface, the implementations of which do 
the actual work of checking the permission.

public interface PermissionResolver
     boolean hasPermission(Object resource, String operation);

We would provide one PermissionResolver implementation out of the box 
with DeltaSpike; PersistentPermissionResolver would provide permission 
checks for ACL-style object permissions and provide a key piece of 
functionality required by a complete permission management API.  
Developers can easily provide their own PermissionResolver 
implementations with custom business logic by simply deploying a 
PermissionResolver bean in their own application.

This pretty much covers the basics of the object permission API, at 
least on the consuming side.  We can discuss this area first before 
moving onto the permission management API shortly.

View raw message