Symfony中的形式和安全性

时间:2015-04-10 12:57:15

标签: forms security symfony

我们想要一个表单,以便用户可以更改/更新自己的评论。 (评论他们留下一篇文章作为例子)。

让我说我得到的所有评论都链接到一篇文章(任何用户的评论)......然后我将其合并到一个表单中。

控制器

$comments = $em->getrepository('comment')->getAllComments_from_an_article($article); // retrun all comments related to an article whatever the author/users of the comments.
$comments = array('comments' => $comments);
$form = $this->createForm(new CommentsType(), $comments);

CommentsType

 builder->add('comments','collection', array('type'=> new commentType() ));

CommentType

 builder->add('comment_text','textarea');

现在我只显示属于当前用户的评论:

{% for comment in form.comments %}
   {% if app.user = comment.user %} {{ form.widget(comment.comment_text) }}
{% endfor %}

我的问题是,这样会安全,还是当前用户可能会编辑其他用户的评论

1 个答案:

答案 0 :(得分:1)

通常最好从安全文章的最后开始并向后工作。所以你想要实现的是:

class CommmentController
{
    public function editAction($request,$comment)
    {
        if (!$this->isGranted('EDIT',$comment)
        {
            throw new AccessDeniedException();

因此,您正在使用现有的安全系统并询问是否允许当前用户更新相关的特定注释。你的CommentVoter实际上是决定的。

切了一下,你的选民可能会像:

class CommentVoter implements VoterInterface
{
public function supportsAttribute($attribute)
{
    return in_array($attribute, array('VIEW','EDIT');
}
// Only deal with comments for this voter
public function supportsClass($class)
{
    // Actually better to inject the class name but oh well
    $supportedClass = 'AppBundle\Entity\Comment';

    return $supportedClass === $class || is_subclass_of($class, $supportedClass);
}
public function vote(TokenInterface $token, $comment, array $attributes)
{
    // Only deal with comments
    if (!$this->supportsClass(get_class($comment))) {
        return VoterInterface::ACCESS_ABSTAIN;
    }
    $user = $token->getUser();

    switch($attributes[0])
    {
      'EDIT':
        // It all comes down to here
        if ($user->getId() === $comment->getUser()->getId()) 
        {
          return VoterInterface::ACCESS_GRANTED;
        }
      break;
    }
    return VoterInterface::ACCESS_DENIED;
}

使用services.yml文件中的条目进行连接:http://symfony.com/doc/current/cookbook/security/voters_data_permission.html#declaring-the-voter-as-a-service

正如您可能想象的那样,您的选民可能更为复杂。例如,管理员用户可能能够编辑所有评论。很容易添加代码。

如果您实施了VIEW权限,那么您的模板将变为:

{% for comment in form.comments %}
 {% if is_granted('VIEW',comment.vars.value) %} {{ form.widget(comment.comment_text) }}
{% endfor %}

希望这能指出你正确的方向。