安全主题 - TWIG 中的 is_granted(ROLE_ADMIN) 是否足够?

Security Topic - IS is_granted(ROLE_ADMIN) in TWIG enough?

我想知道是否仅在树枝中执行 is_granted(ROLE_ADMIN) 就足以确保表单安全。

我的意思是任何人都可以使用该表格:
- 一些带有选项的小部件可供任何人更改。
- 其他小部件(关于相同形式的管理的小部件)仅在授予 ROLE_ADMIN 时显示。

仅由 ROLE_ADMIN 更改此表单中的管理内容是否足够安全?或者我应该保护控制器。

(保护控制器会让我写更多,因为现在我只需要做一个 flush()。然后我将不得不为所有 POST 我通过表单请求)

一般建议

这取决于您所说的安全是什么意思。而且,这也取决于您对 足够安全 的定义。

以下问题可能会有所帮助:

  • 它是否是内部使用的应用程序(例如公司内部的日历应用程序,其中没有存储或公开敏感数据)
  • 针对故意格式错误的请求确保安全性是否重要(每次第一个问题的答案是 'yes' 时我都会考虑)。但是,即使前一个问题的答案是 'no',有时即使在内部日历应用程序中,您也可能会收到格式错误的请求……这完全取决于您认为什么是安全威胁,什么不是。并且,对您的用户。

如果您没有在控制器中保护它,那么用户可能会提交一个任意的 POST 请求,其中包含未显示在此处的字段,如果她猜对了字段的名称,或者发现他们在某个地方。因此,在我看来,您应该始终仔细检查是否正常。

你可以:

  • ('pure'解决方案,比较费时) 通过根据用户权限动态生成表单类型来分离管理小部件。然后你总是可以在 HTML 代之前检查它们在 Twig 中的存在。如果您不使用 FormType,那么我建议您这样做 - 但即使您在控制器中构建整个表单,您也可以动态添加字段。
  • ('dirty' 解决方案,但实施起来简单快捷)在控制器中处理表单提交时检查该角色(您建议)。

作为对您在评论中的问题的回答:"how can I simulate a POST to check if the token is enough to block POST field which are not actually display in my page." 如果您使用 Google Chrome 进行开发,我可以向您推荐 Chrome Advanced Rest Client 扩展。我用它来测试我的表格并取得了巨大成功。

所以,综上所述,我认为问题表述不明确,无法笼统回答。这一切都取决于。但如果你想要一个简单的答案:它不够安全。从某人的眼睛隐藏某些东西并不意味着它是安全的。因此...

具体推荐——带有表单事件监听器的解决方案

为了获得最大的安全性,我会这样做(我在这里使用 PHP 5.5,因此请确保您拥有它,否则它需要进行一些语法调整)。

在您的 FormType 中注册一个事件侦听器,如下所示:

(...)

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('product_id', 'hidden');

    (...)

    $dynamicFieldCreatorFunc = function (FormEvent $event)
    {
        $data = $event->getData();
        $form = $event->getForm();

        if ($this->getContainer()->get('security.context')->isGranted('ROLE_ADMIN'))
        {
            $form->add('admin_field', 'choice', [
                'choices' => [1 => 'Choice 1', 2 => 'Choice 2'],
            ]);
        }
    };

    $builder->addEventListener(FormEvents::PRE_SET_DATA, $dynamicFieldCreatorFunc);
    $builder->addEventListener(FormEvents::PRE_SUBMIT, $dynamicFieldCreatorFunc);
}

然后,如果用户不是管理员用户,您的表单将不会生成这些字段。当然,在 Twig 中,如果你一个一个地渲染你的小部件,你应该在渲染它们之前检查该字段是否存在:

{% if form.admin_field is defined %}
    {{ form_widget(form.admin_field) }}
{% endif %}

或者,在最新的 Twig 中使用更短的语法

{% form.admin_field is defined ? form_widget(form.admin_field) }}