Symfony2 ACL 与另一个标准相结合
我想知道是否有人知道使用 Symfony2 ACL 系统实现此目的的优雅方法。
我有一个 Comment
实体(我的域对象),需要由 ROLE_USER
进行编辑,但这仅在评论发布后 5 分钟内允许 - 否则评论只能由ROLE_ADMIN
编辑。
使其只能由 ROLE_USER
和 ROLE_ADMIN
编辑很简单,只需为每个角色创建一个 RoleSecurityIdentity
即可。
现在,当我想合并 ROLE_USER
的时间因素时,我的问题就出现了。我的第一个问题是它需要来自域对象的信息,而不仅仅是 ACL 表,但我认为这可以通过创建一个自定义 ObjectIdentity
类来解决,该类也可以保存 Comment< /code> 已发布。
现在是最困难的部分,
我想我需要创建一个自定义的PermissionGrantingStrategy
,它知道还要查看创建时间。当检查 Comment
类型时必须加载它,但我不知道如何加载它。有谁知道是否有某种工厂可以配置此类事情?因此,如果一个实体具有与其关联的特定 PermissionGrantingStrategy ,那么它就会被使用,否则将使用默认值?
我知道这有点长,如果有人知道如何实现这一点,非常感谢,因为 ACL 文档目前似乎有点稀疏。我的后备解决方案是简单地提供某种服务来检查评论是否可以编辑,而根本不用担心 ACL。
I'm wondering if anyone knows of an elegant way to achieve this using the Symfony2 ACL system.
I have a Comment
entity (my domain object) which needs to be editable by ROLE_USER
but this is only allowed within 5 minutes of the comment being posted - otherwise the comment can only be edited by ROLE_ADMIN
.
Making it so that it can only be edited by ROLE_USER
and ROLE_ADMIN
is simple, just make a RoleSecurityIdentity
for each.
Now my problem occurs when I want to incorporate the time factor for ROLE_USER
. My first problem is that it needs information from the domain object, not just the ACL table but I think this is solvable by making a custom ObjectIdentity
class which can also hold the time that the Comment
was posted.
Now for the hard part
I think I need to create a custom PermissionGrantingStrategy
that knows to also look at the creation time. This has to be loaded when a Comment
type is being checked, but I don't know how to get it to load. Does anyone know if there's some kind of factory through which this sort of thing can be configured? So that if an entity has a specific PermissionGrantingStrategy
associated with it then it gets used otherwise the default is used?
I know this is a bit of a long one, many thanks if anyone knows how to achieve this as the ACL documentation seems a tad sparse at the moment. My fallback solution is to simply make some kind of service to check if a Comment can be edited and not bother with ACL at all.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我发布这个解决方案,以便其他人可以看到我的最终代码,但以下是我在按照有问题的建议实现投票器时发现的陷阱。
supportsAttribute:当您在
SecurityContext
上调用isGranted
方法时,它似乎在委托之前实际上并没有检查此方法vote
调用VoterInterface
,因此在您的vote
方法中,您实际上必须自己检查属性。supportsClass:在上面有问题的答案中,似乎这个方法可能是基于工厂的选择的关键,其中
VoterInterface
可以投票,但实际上 symfony2 文档是这样写的:因此,它实际上似乎与
Voter
是否支持令牌类型有关。更糟糕的是 PHP 文档似乎很模糊:无论如何,主要问题是在将调用委托给任何投票者的
vote
方法之前,SecurityContext
永远不会检查此方法 - 即使此方法被硬编码为返回 false
投票
仍将被调用!所以基本上这个故事的寓意似乎是:检查
$attributes
和$object
手动进入vote
方法。我的代码:
services.yml
和选民类别:
最后是模板:
我希望这对将来的其他人有帮助,并非常感谢 Problematic 为我指明了方向的选民。
I'm posting this solution so that others can see my final code but here are the pitfalls I found when implementing a Voter as Problematic suggested.
supportsAttribute: It appears that when you call the
isGranted
method on theSecurityContext
that it doesn't actually check this method before delegating avote
call to aVoterInterface
so inside yourvote
method you actually have to check the attributes yourself.supportsClass: In problematic's answer above it seemed like this method could be a key for a Factory based selection of which
VoterInterface
s can vote but actually the symfony2 documentation reads:Therefore it actually seems to pertain to whether or not the
Voter
supports the token type. To make matters worse the PHP Doc seems vague:At any rate the main problem is that this method is never checked by the
SecurityContext
before delegating the call to thevote
method of any voter - even if this method is hardcoded toreturn false
vote
will still be called!So basically the moral of the story appeared to be: check the
$attributes
and$object
coming in on thevote
method manually.My Code:
services.yml
and the voter class:
and finally template:
I hope this helps someone else in the future and a big thanks to Problematic for pointing me in the direction of Voters.
您是否考虑过使用选民?有一个用于实现 IP 黑名单投票者的 食谱,但可以轻松修改它以处理检查用于对 Comment 对象进行编辑。
您可以在
Symfony\Component\Security\Acl\Voter\AclVoter
查看默认的 AclVoter(在线 此处),尽管您的显然可以增强而不是替换它并且更简单。作为概念的快速证明:
Have you considered using a voter? There's a cookbook recipe for implementing an IP blacklist voter, but it could be easily modified to handle checking for edits on Comment objects.
You can look at the default AclVoter at
Symfony\Component\Security\Acl\Voter\AclVoter
(online here), though yours can obviously augment instead of replace it and be much simpler.As a quick proof of concept: