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 <[email protected]
> wrote:
> Applied, excellent patch thanks!
>
> Kalle
>
> On Thu, Oct 11, 2012 at 3:35 PM, Dmitry Gusev <[email protected]>
> wrote:
> > Done:
> >
> > http://jira.codehaus.org/browse/TYNAMO-183
> >
> >
> > On Fri, Oct 12, 2012 at 1:46 AM, Dmitry Gusev <[email protected]
> >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 <[email protected]
> >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 <
> >>> [email protected]> 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 <[email protected]
> >
> >>>> 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: [email protected]
> >>>> For additional commands, e-mail: [email protected]
> >>>>
> >>>>
> >>>
> >>>
> >>> --
> >>> 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: [email protected]
> For additional commands, e-mail: [email protected]
>
>
--
Dmitry Gusev
AnjLab Team
http://anjlab.com