deltaspike-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gerhard Petracek <gerhard.petra...@gmail.com>
Subject Re: [DISCUSS] DELTASPIKE-79 Authorization API
Date Sun, 22 Apr 2012 17:21:35 GMT
hi @ all,

> @SecurityRole(name = "admin")

if i remember correctly, we agreed on improving @SecurityBindingType to
allow such a (custom) annotation easily.

> PermissionResolver + PermissionType:

that wouldn't be a resolver. a resolver just resolves the information.
a voter or evaluator should do the calculation (right now we have a
AccessDecisionVoter in place - we can refactor it and add the concepts
of ResourceIdentifier and Operation to AccessDecisionVoterContext or
ResourceAwareAccessDecisionVoterContext).

> ResourceIdentifier:

+1 (but it should be an interface)
and we should do the same with the operation/action - e.g.:

public interface Operation
{
}

public enum CrudOperation implements Operation
{
    CREATE, READ, UPDATE, DELETE
}

->
identity.hasPermission(new CustomerResourceIdentifier(customer),
CrudOperation.UPDATE)

> el use-case:
imo we don't need it right now. the upcoming jsf-module (or
el-security-module) can provide a helper which provides it.
we can even keep the bean-name "identity", because the security-module
doesn't need to provide such a named bean.

regards,
gerhard



2012/4/19 Bruno Oliveira <bruno@abstractj.org>

> 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 <sbryzak@redhat.com> wrote:
>
> > On 19/04/12 06:35, Bruno Oliveira wrote:
> >
> >> On Tue, Apr 17, 2012 at 7:52 PM, Shane Bryzak<sbryzak@redhat.com>
>  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.
> >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message