使用Symfony2管理用户/组对象权限的最佳方法

时间:2022-10-22 16:54:44

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.

每个父对象(如场所)作为user_id和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.

工作正常(在symfony 1.4中),但它很乱 - 任何事情的每个查询都必须进行复杂的连接以获得可能的组等...我们想找到一种更简单的方法。

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).

我对Sf2 ACL组件感到非常兴奋,但我被一遍又一遍地告诉我不应该用它来查找用户可以管理的对象 - 而是我应该使用ACL来查明用户是否被允许管理自己的对象对象(似乎没有用,但无论如何)。

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.

我发现在网上进行的所有替代尝试都是为了从db中提取所有对象,然后通过ACL过滤 - 这对于妈妈和流行网站来说很可爱 - 不会发生在一百万个对象上。

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.

所以...我很想听听关于我们如何做到这一点的想法 - 我们也愿意让symfony留下具有可扩展ACL解决方案的东西,但到目前为止还没有找到任何东西(php或ruby)如此开放尽管我们希望继续使用Sf。请注意,我们打算在重要的情况下使用MongoDB。

2 个解决方案

#1


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).

根据我的理解,ACL用于在特殊情况下为特定人员提供特定对象的访问权限。您所描述的内容更为通用,但它只是偏离了Symfony2为安全性所概述的内容(此人具有“管理员”角色,但仅适用于特定组中包含的对象)。

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...

ACL不应该用于存储一堆东西,因为如果它太大,检查它会变得昂贵。因此,在添加新用户时,或者甚至在组中添加新对象时,默认情况下会抛出一堆东西(如果使用ACL,则无论何时创建一个组,都必须向组中的每个人添加一个条目新对象),一段时间后会对性能产生负担......

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:

我目前正在研究将Symfony2用于网络应用程序的可能性,但我也在使用这种安全性问题,因为我们有类似的需求。我不是Symfony2的专家,但从我所看到的,你可能有几个选择:

  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

    创建一个选民来处理这个问题。选民允许您检查授权令牌,并根据您的处理方式返回授予或拒绝访问权限。因此,您可以创建一个自定义选项,用于检查用户的组并尝试将其与该对象所在的组进行匹配。如果是这样,如果选民对当前检查无效,则返回ACCESS_GRANTED,否则返回ACCESS_DENIED或ACCESS_ABSTAIN。编辑:这是一个指向Symfony2选民食谱的链接: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.

    可能还想研究SecurityContext接口。这提供了“isGranted()”方法,用于确定对对象的访问。如果选民不够简单,你可能必须走创建一个新的SecurityContext类的路线;我认为这会涉及到更多一点。

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.

就像我说的,我不是专业人士,也没有解决方案;这些只是我正在研究的一些方向,试图解决(我的感觉)类似的问题。希望这有点帮助。

#2


1  

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.

虽然Symfony提供了一个安全/ ACL层,但您不必使用它,或者至少完全使用它。

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.

在您的代码中的任何时间点,您都可以抛出Symfony \ Component \ Security \ Core \ Exception \ AccessDeniedException,安全层将“启动”并为您处理,例如将用户重定向到登录页面等。

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.

长话短说,虽然Symfony提供了一些很好的机制和功能来帮助构建ACL,但您不必努力使您的数据和流程适合他们定义的内容。

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.

以我们的系统为例,我们的系统中包含帐户,角色和组(以及权限)。我们还将部分数据划分为部门。虽然用户可以拥有全局级别的角色和权限,但他们也可以拥有特定于部门的访问权限。这种设置使用内置的Symfony ACL功能和访问检查工具几乎无法使用(并不意味着他们的工具没用,实际上它们很棒,它们不适合我们的用例)。因此,我们构建了自己的服务(利用一些微调查询),我们传入有关检查的相关数据,并在检查失败时抛出相应的Symfony \ Component \ Security \ Core \ Exception \ AccessDeniedException。

#1


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).

根据我的理解,ACL用于在特殊情况下为特定人员提供特定对象的访问权限。您所描述的内容更为通用,但它只是偏离了Symfony2为安全性所概述的内容(此人具有“管理员”角色,但仅适用于特定组中包含的对象)。

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...

ACL不应该用于存储一堆东西,因为如果它太大,检查它会变得昂贵。因此,在添加新用户时,或者甚至在组中添加新对象时,默认情况下会抛出一堆东西(如果使用ACL,则无论何时创建一个组,都必须向组中的每个人添加一个条目新对象),一段时间后会对性能产生负担......

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:

我目前正在研究将Symfony2用于网络应用程序的可能性,但我也在使用这种安全性问题,因为我们有类似的需求。我不是Symfony2的专家,但从我所看到的,你可能有几个选择:

  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

    创建一个选民来处理这个问题。选民允许您检查授权令牌,并根据您的处理方式返回授予或拒绝访问权限。因此,您可以创建一个自定义选项,用于检查用户的组并尝试将其与该对象所在的组进行匹配。如果是这样,如果选民对当前检查无效,则返回ACCESS_GRANTED,否则返回ACCESS_DENIED或ACCESS_ABSTAIN。编辑:这是一个指向Symfony2选民食谱的链接: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.

    可能还想研究SecurityContext接口。这提供了“isGranted()”方法,用于确定对对象的访问。如果选民不够简单,你可能必须走创建一个新的SecurityContext类的路线;我认为这会涉及到更多一点。

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.

就像我说的,我不是专业人士,也没有解决方案;这些只是我正在研究的一些方向,试图解决(我的感觉)类似的问题。希望这有点帮助。

#2


1  

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.

虽然Symfony提供了一个安全/ ACL层,但您不必使用它,或者至少完全使用它。

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.

在您的代码中的任何时间点,您都可以抛出Symfony \ Component \ Security \ Core \ Exception \ AccessDeniedException,安全层将“启动”并为您处理,例如将用户重定向到登录页面等。

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.

长话短说,虽然Symfony提供了一些很好的机制和功能来帮助构建ACL,但您不必努力使您的数据和流程适合他们定义的内容。

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.

以我们的系统为例,我们的系统中包含帐户,角色和组(以及权限)。我们还将部分数据划分为部门。虽然用户可以拥有全局级别的角色和权限,但他们也可以拥有特定于部门的访问权限。这种设置使用内置的Symfony ACL功能和访问检查工具几乎无法使用(并不意味着他们的工具没用,实际上它们很棒,它们不适合我们的用例)。因此,我们构建了自己的服务(利用一些微调查询),我们传入有关检查的相关数据,并在检查失败时抛出相应的Symfony \ Component \ Security \ Core \ Exception \ AccessDeniedException。