Hi Shane, if I'm following your thought the idea is to have security on
object-level and not just check methods (resource level) as I was thinking
with @CheckPermissions on the method level.

About filterDeniedInvocations I got it borrowed from SecurityInterceptor.
I'm checking permissions on the method level only without going too deep
with object-level.

Thanks for clarify.

On Wed, Apr 18, 2012 at 7:02 PM, Shane Bryzak <[email protected]> wrote:

> On 19/04/12 06:35, Bruno Oliveira wrote:
>
>> 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?
>>
>
> Hi Bruno.  Probably both, we definitely need a programmatic API (the
> hasPermission() method below) but I think a security binding type is also
> useful (also detailed below).
>
>
>
>>
>>> Identity.hasPermission(Object resource, String operation)
>>>
>>>  Does 'operation' here means CRUD operations?
>>
>
> CRUD would be supported here but the operation is not limited to CRUD, it
> can potentially be anything.
>
>
>
>>
>>> 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
>>     }
>> }
>>
>
> This is an example of coarse-grained security, whereas ACL is fine-grained
> (object-level) security.
>
>
>
>>
>>  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.
>>
>
> How would you support specifying permission checks on multiple parameters
> of different types?


>
>
>>  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
>> }
>>
>
> Not sure what you're suggesting here - could you please elaborate?
>
>
>
>>  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?
>>
>
> This is really just an implementation detail, but I think a
> Map<Class,PermissionResolver> would be sufficient.
>
>
>
>>  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.
>>
>>
>>
> I guess it will depend on whether we introduce any/many changes as a
> result of discussion.  This is just a small part of the authorization API
> and really requires some of the other parts (in particular permission
> management) to be really useful.
>
>

Reply via email to