Thanks, Kalle!

I've attached another patch to the same issue that does the same thing for
component method interceptors.

FYI:
Here's how my implementation of ILAC looks like.
I implemented abstraction layer of permission controllers that allows:

   - automatically pick right controller by permission domain. For
   instance, ProjectPermissionController will be used to check permissions for
   "project:view:1" (see below)
   - extract target instance key/id from permission, if permission is in
   the form of "domain:action:target" and perform lookup by this key

This may be helpful if you do permission check from code like this:

securityService.hasPermission("project:" + permissionAction + ":" + project
.getId());

   - extract target instance from intercepted method argument. Controller
   may use object instance from parameter as-is if available:


    @RequiresPermissions(PermissionConstants.PROJECT_EDIT_CORRECTIONS)

    @CommitAfter

    Resolution updateResolution(Project project, String word, Resolution
resolution);

   - ... or get instance key/id from parameters and perform instance lookup
   by this key:


    @RequiresPermissions(PermissionConstants.TASK_CANCEL)

    void cancelTask(int taskId);


Permission controllers may be contributed in AppModule:

    @Contribute(ILACAuthorizingRealm.class)

    public static
voidaddPermissionControllers(OrderedConfiguration<PermissionController>
conf)

    {

        conf.addInstance("project", ProjectPermissionController.class);

    }

Example of PermissionController:

public class ProjectPermissionController
extendsAbstractILACPermissionController<Integer, Project>

{

    private final ProjectManager projectManager;


    public ProjectPermissionController(Environment environment,

                                       TypeCoercer coercer,

                                       ProjectManager projectManager)

    {

        super(environment, coercer, "project:*");



        this.projectManager = projectManager;

    }



    @Override

    public boolean isPermitted(PrincipalCollection principals,

                               ILACPermission permission,

                               Project project)

    {

        if (project == null)

        {

            //  Project not found == Access forbidden

            return false;

        }



        //  TODO Check ACL for the project



        return true;

    }



    @Override

    protected Class<Project> getInstanceClass()

    {

        return Project.class;

    }



    @Override

    protected Class<Integer> getInstanceKeyClass()

    {

        return int.class;

    }



    @Override

    protected Project lookupInstanceByKey(Integer key)

    {

        return projectManager.findById(key);

    }


}

On Fri, Oct 12, 2012 at 11:39 AM, Kalle Korhonen <kalle.o.korho...@gmail.com
> wrote:

> Applied, excellent patch thanks!
>
> Kalle
>
> On Thu, Oct 11, 2012 at 3:35 PM, Dmitry Gusev <dmitry.gu...@gmail.com>
> wrote:
> > Done:
> >
> > http://jira.codehaus.org/browse/TYNAMO-183
> >
> >
> > On Fri, Oct 12, 2012 at 1:46 AM, Dmitry Gusev <dmitry.gu...@gmail.com
> >wrote:
> >
> >> Using @Core annotation helped:
> >>
> >>  @Match("*")
> >>
> >> @Order("before:*")
> >>
> >> public static void adviseSecurityAssert(MethodAdviceReceiver receiver,
> >>
> >> final @Core Environment environment)
> >>
> >>
> >> On Fri, Oct 12, 2012 at 12:59 AM, Dmitry Gusev <dmitry.gu...@gmail.com
> >wrote:
> >>
> >>> Ok, I'm working on the patch now.
> >>>
> >>> I have a problem injecting Environment instance into advisor method in
> >>> SecurityModule:
> >>>
> >>>  @Match("*")
> >>>
> >>> @Order("before:*")
> >>>
> >>> public static void adviseSecurityAssert(MethodAdviceReceiver receiver,
> >>>
> >>> final Environment environment)
> >>>
> >>> this issue was already filed in JIRA:
> >>>
> >>> https://issues.apache.org/jira/browse/TAP5-1045
> >>>
> >>>
> >>> Caused by: java.lang.IllegalStateException: Construction of service
> >>> 'AssetObjectProvider' has failed due to recursion: the service depends
> on
> >>> itself in some way. Please check
> >>> org.apache.tapestry5.internal.services.AssetObjectProvider(AssetSource,
> >>> TypeCoercer, SymbolSource) (at AssetObjectProvider.java:45) via
> >>> org.apache.tapestry5.services.TapestryModule.bind(ServiceBinder) (at
> >>> TapestryModule.java:308) for references to another service that is
> itself
> >>> dependent on service 'AssetObjectProvider'.
> >>>
> >>> at
> >>>
> org.apache.tapestry5.ioc.internal.RecursiveServiceCreationCheckWrapper.createObject(
> >>> RecursiveServiceCreationCheckWrapper.java:52)
> >>>
> >>>
> >>>
> >>> On Thu, Oct 11, 2012 at 8:49 PM, Kalle Korhonen <
> >>> kalle.o.korho...@gmail.com> wrote:
> >>>
> >>>> Instance-level access control is a very interesting topic to me. I say
> >>>> you are pretty much on the right track if you want to use the
> >>>> permission model. You wouldn't *necessarily* need to change anything
> >>>> in Shiro if you just did programmatic checks with isPermitted and you
> >>>> knew the right permissions at the time you are creating the
> >>>> AuthorizationInfo. However, that model is cumbersome as you need to
> >>>> create all the permissions upfront and then later formulate specific
> >>>> ones when doing an authorization check - and you still couldn't use
> >>>> annotations. Alex' syntax is one way to go about and you certainly
> >>>> need some property substitution syntax for doing instance level checks
> >>>> with annotations. Using the environment for fetching the
> >>>> MethodInvocation sounds reasonable and I'm open to adding that as a
> >>>> patch to tapestry-security. That way everybody at least wouldn't need
> >>>> to introduce their own annotations.
> >>>>
> >>>> Entity-Relationship Based Access control is a completely different
> >>>> take on the same topic. It's based on the idea that the data objects
> >>>> you are trying to secure are in one way or another associated to the
> >>>> currently executing subject. It greatly simplifies the syntax required
> >>>> but obviously limits the possibilities as well. You wouldn't
> >>>> necessarily need a "DAO" but still, some single, uniformed way of
> >>>> accessing the data objects. The current implementation works at the
> >>>> (JPA) EntityManager level.
> >>>>
> >>>> Kalle
> >>>>
> >>>>
> >>>> On Thu, Oct 11, 2012 at 6:38 AM, Dmitry Gusev <dmitry.gu...@gmail.com
> >
> >>>> wrote:
> >>>> > Hi,
> >>>> >
> >>>> > I need to implement instance-level access control in my application
> >>>> using
> >>>> > tapestry-security.
> >>>> >
> >>>> > I already asked similar question here [1].
> >>>> >
> >>>> > There Taha suggested to use AuthorityVoter, but that wasn't Tynamo's
> >>>> > tapestry-security.
> >>>> >
> >>>> > I looked at Entity-Relationship Based Access Control [2].
> >>>> >
> >>>> > This is not exactly what I need, because I don't even have DAO layer
> >>>> > involved here.
> >>>> >
> >>>> > Here's what I have. I have business method in one of my services:
> >>>> >
> >>>> >     @RequiresPermissions("task:submit")
> >>>> >
> >>>> >     void submitTask(Task newTask);
> >>>> >
> >>>> > I read about ILAC on Shiro's web site [2].
> >>>> >
> >>>> > This looks similar, but in my domain not every user may submit every
> >>>> task
> >>>> > for execution.
> >>>> > I have custom logic that should inspect instance of the newTask and
> >>>> decide
> >>>> > whether current user has permissions to submit the task for
> execution
> >>>> or
> >>>> > not.
> >>>> >
> >>>> > In Shiro's documentation [3] there's a note that tells that a
> >>>> developer may
> >>>> > write its own implementation of AuthorizingRealm.isPermitted(*) to
> >>>> check
> >>>> > permissions against custom domain model. I'm not sure about this in
> my
> >>>> > case, though, because this note is given in 'Performance
> >>>> Considerations'
> >>>> > section.
> >>>> >
> >>>> > One more thing that stops me from overriding
> >>>> AuthorizingRealm.isPermitted(*) is
> >>>> > I don't have access to invocation context, i.e. I can't get instance
> >>>> of the
> >>>> > newTask from example above:
> >>>> >
> >>>> >         AuthorizingRealm realm = new AuthorizingRealm()
> >>>> >
> >>>> >         {
> >>>> >
> >>>> >             @Override
> >>>> >
> >>>> >             public boolean isPermitted(PrincipalCollection
> principals,
> >>>> > Permission permission) {
> >>>> >
> >>>> >                 //  XXX ... can't access to newTask instance
> >>>> >
> >>>> >             }
> >>>> >
> >>>> >
> >>>> > I was thinking about fixing Tynamo's SecurityInterceptor advise, by
> >>>> putting
> >>>> > MethodInvocation into Tapestry Environment service instance and
> getting
> >>>> > this MethodInvocation from there in realm.
> >>>> >
> >>>> > Am I in the right direction? Any suggestions?
> >>>> >
> >>>> >
> >>>> >
> >>>> > [1]
> >>>> >
> >>>>
> http://tapestry.1045711.n5.nabble.com/ANN-A-Tapestry5-Based-Security-Module-tp3322452p3338137.html
> >>>> > [2] http://tynamo.org/tapestry-security-jpa+guide
> >>>> > [3]
> >>>> >
> >>>>
> http://shiro.apache.org/permissions.html#Permissions-InstanceLevelAccessControl
> >>>> > [4]
> >>>> >
> >>>>
> http://shiro.apache.org/permissions.html#Permissions-PerformanceConsiderations
> >>>> >
> >>>> > --
> >>>> > Dmitry Gusev
> >>>> >
> >>>> > AnjLab Team
> >>>> > http://anjlab.com
> >>>>
> >>>> ---------------------------------------------------------------------
> >>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> >>>> For additional commands, e-mail: users-h...@tapestry.apache.org
> >>>>
> >>>>
> >>>
> >>>
> >>> --
> >>> Dmitry Gusev
> >>>
> >>> AnjLab Team
> >>> http://anjlab.com
> >>>
> >>
> >>
> >>
> >> --
> >> Dmitry Gusev
> >>
> >> AnjLab Team
> >> http://anjlab.com
> >>
> >
> >
> >
> > --
> > Dmitry Gusev
> >
> > AnjLab Team
> > http://anjlab.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>


-- 
Dmitry Gusev

AnjLab Team
http://anjlab.com

Reply via email to