【问题标题】:Can I use voters to DELETE item in a collection我可以使用选民删除集合中的项目吗
【发布时间】:2015-04-15 10:46:19
【问题描述】:

我想使用选民来增强我的代码的安全性。我希望只有一些用户能够删除项目集合。

这里是我的例子:
我有一篇文章和与文章相关的标签。我希望文章的作者能够删除与该文章关联的标签(只有文章的作者可以这样做)

我正在考虑使用选民(检查用户是否是文章的作者),但我在互联网上找到的每个示例都显示从树枝或控制器调用的选民......而收集选项 "allow-delete" symfony 从实体 Article 调用方法 removeTag($tag)。我也看不到如何/在哪里可以召集选民。

【问题讨论】:

  • 假设我不知道您的用例,并且我认为必须始终应用此检查类型,然后才能访问您可以 delete 标签(在控制器中)的操作,但是为了尝试回答您的具体问题,您如何看待在 Article 实体中添加自定义验证器,然后在其中调用相关选民?或者您可以调用控制器中的投票者,然后将结果传递给表单构建器以设置allow_delete => false。在任何情况下,您都可以向用户添加适当的错误消息。
  • @gp_sflover 感谢您的帮助。如何在文章实体中添加自定义验证器,然后在相关选民中调用?验证器不能实现为 get 或 is 以外的方法......而我希望对 removeTag 或类似的东西进行检查......

标签: symfony collections symfony-security


【解决方案1】:

答案可能是这样的:

是的,你可以,在你想要的地方注入 service.container 并调用$this->securityContext->isGranted('delete', $tag);

但这意味着您需要在您的实体中注入服务,这是完全错误的。

另一种方法是在 preRemove 或 onFlush 事件的原则侦听器中执行此操作,这很酷但几乎是错误的,如果选民失败了怎么办?如果您抛出异常,这将破坏教义。如果没有用户,还会发生什么?原因是在监听器中你不能轻易地向用户返回反馈。

在更高的抽象级别上阻止实体删除是错误的,因为您可以在更好、更易于管理的地方进行操作,而不会在代码库的其他远程位置产生错误。

试试这个:

  • 如果你使用 symfony 表单,你可以做以下两件事之一:
    • 使用表单约束作为服务,在此处注入安全上下文并进行验证,如果错误添加表单错误
    • 创建一个自定义表单类型作为服务,集合作为父项,注入 security.context,最后在 PRE_SET_DATA 上使用表单侦听器检查是否删除了某些内容并检查当前用户是否允许使用 isGranted,如果检查失败添加一个表单错误
  • 如果您在单个操作中执行此操作(例如 api),您只需要直接在您的操作中或在您的树枝中检查 isGranted

【讨论】:

  • 感谢 Marino 为您解答。你能否给我更多关于你的第一个解决方案的细节。 将约束作为服务,注入安全上下文...这对我有很大帮助。
  • 很遗憾,今天我没有时间给你写一个完整的解决方案symfony.com/doc/current/cookbook/validation/… 跟着这个,有一个关于如何做一个约束作为服务的解释。困难的部分是在你这样做之后,你需要能够知道集合的已删除元素,最简单的方法是使用表单事件在验证器中设置原始集合symfony.com/doc/current/cookbook/form/…
  • 另一种方法是使用理论计算实体变更集或更容易将已删除的项目存储在实体中的某处(调用 removeTag 时在数组中移动)
  • 我选择使用约束作为服务。到目前为止,我想使用与方法 deleteTag() 关联的验证 deletetag,但 symfony 说它只能使用验证器,方法以 get 或 is 开头。你能帮我解决这个问题吗?我做了其他所有事情,只是这部分还没有成功。
  • 您应该验证“标签”,以其他方式跟踪初始标签
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-20
  • 2014-03-08
  • 2014-10-10
相关资源
最近更新 更多