On Tue, Apr 17, 2012 at 7:52 PM, Shane Bryzak <[email protected]> wrote:
> 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:
>
Hi Shane, good catch start to talk about it. Are you thinking about
something using CDI interceptors or observers? To permission checks?
>
>
> Identity.hasPermission(Object resource, String operation)
>
Does 'operation' here means CRUD operations?
>
>
> 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
> }
>
I like your idea. Currently I'm working on something similar to it with
interceptors:
@RequestScoped
public class DummyService {
@SecurityRole(name = "admin")
public void editCustomer(Customer customer) {
//Something here
}
}
>
> We could potentially also do some clever stuff with method-level
> annotations here. Off the top of my head, something like this might work:
>
> @CheckPermissions
> public void editCustomer(@CheckPermission(**"EDIT") Customer customer)
>
It would be great to specify "EDIT" on top of the method only
with @CheckPermission annotation.
>
> 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.
>
Do you think that's a good idea do something like this?
@AroundInvoke
public Object filterDeniedInvocations(InvocationContext invocationContext)
throws Exception {
//read annotation value here with parameter list and perform checks
}
>
> 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.
>
How do you think to cache it?
>
> 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.
>
> What do you think about a separated branch to prototype it? Let me know if
I could help with something.
--
--
"Know the rules well, so you can break them effectively" - Dalai Lama XIV
-
@abstractj
-
Volenti Nihil Difficile