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.