Best way to manage user/group object permissions with Symfony2
Asked Answered
L

2

12

I'd like to hear some thoughts on the best way to optimize our schema to achieve the following.

We have a number of objects/db entries (events, venues, etc) some of which have children objects (meaning the same permissions apply - images, metas, etc)

Users can belong to groups so parent objects such as events, venues can be editable/viewable by all, group only, just one user.

Currently we have a user, usergroup and group table to manage users and groups.

Each parent object such as venues as a column for user_id and group_id.

Works fine (in symfony 1.4) but it's messy - every query for anything has to do complex joins to get possible groups etc... We'd like to find a simpler way.

I was really excited about the Sf2 ACL component but I am being told over and over that I should not use it to find objects that a user can manage - rather that I should use ACL to find out if a user is allowed to manage his own objects (doesn't seem very useful but whatever).

All alternative attempts online that I found to do this say to pull all objects from db then filter by ACL - it's cute for a mom and pop site - not gonna happen with a million objects.

So... I would love to hear ideas as to how we could do this - we are also open to leaving symfony for something that has a scaleable ACL solution but have not found anything so far (php or ruby) so open to that as well though we would love to continue using Sf. Note that we intend to use MongoDB in case that matters.

Lamonica answered 11/3, 2012 at 5:39 Comment(0)
A
11

From how I understand it, the ACL is used to give access to a specific object to a specific person for special scenarios. What you are describing is more generic, but it just deviates from what Symfony2 outlines for security (this person has an "admin" role, but only for the objects contained in a particular group).

ACLs should not be used to store a bunch of stuff, as checking it can get expensive if it gets too large. So, throwing a bunch of stuff in here by default when new users are added, or even when new objects are added under a group (if using the ACL, you would have to add an entry to each person in the group whenever you create a new object), is going to be taxing on performance after a while...

I am currently researching the possibility of using Symfony2 for a web app, but I am hitting a wall with this security stuff too, as we have a similar need. I'm no expert on Symfony2, but from what I have looked in to, you might have a few options:

  1. Create a Voter to handle this. Voters allow you to check authorization tokens and return whether access is granted or denied based on how you process it. So, you could make a custom Voter that checks a user's group and tries to match it up with the group the object is under. If so, return ACCESS_GRANTED, otherwise ACCESS_DENIED, or ACCESS_ABSTAIN if the Voter is not valid for the current check. EDIT: Here is a link to the Symfony2 cookbook for Voters: http://symfony.com/doc/current/cookbook/security/voters.html

  2. Might also want to research the SecurityContext interface. This provides the "isGranted()" method that deals with determining access to objects. If Voters are not simply enough, you might have to go the route of creating a new SecurityContext class; I think that this would be a bit more involved though.

Like I said, I am no pro, and don't have a solution; these are just some directions I am researching to try to solve (what I feel is) a similar problem. Hope this helps somewhat.

Ally answered 15/4, 2012 at 6:13 Comment(0)
A
2

It's been a while since I posted my original answer to this, but wanted to follow up with another solution, one which we are using currently.

While Symfony gives a security/ACL layer to use, you don't have to use it, or at least fully.

At just about any point in time in your code, you can throw a Symfony\Component\Security\Core\Exception\AccessDeniedException and the security layer will "kick in" and handle it for you, like redirecting users to a login page, etc.

Some of this interaction may require a bit more advanced firewall setup to work exactly how you want it to.

Long story short, while Symfony provides some great mechanisms and features to help build ACL, you don't have to work to fit your data and processes into what they have defined.

For our system as an example, we have Accounts, Roles, and Groups in our system (along with Permissions). We also divide sections of data off into Departments as well. While users can have global-level Roles and Permissions, they can also have Department-specific access. This setup made using the built in Symfony ACL features and access checking tools almost unusable (not meaning their tools are useless, they are great in fact, they just don't fit our use case). So, we built our own service (that utilizes some fine-tuned queries) where we pass in the relevant data concerning a check and it throws the appropriate Symfony\Component\Security\Core\Exception\AccessDeniedException when a check fails.

Ally answered 19/1, 2016 at 6:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.