最好的设计,以确保用户只能访问他们的信息

时间:2017-11-07 14:24:03

标签: symfony doctrine-orm

我有一个带有doctrine的symfony2.7应用程序,它有大量的实体,其中很多实体都依赖于单个实体,让我举一个例子来澄清

学校有很多学生, 学生有很多课, 课程有很多测试, 测试有多个等级

请想象一下像这样的数据库设计,但更大,允许许多学校。假设您有一个角色“SCHOOL_DIRECTOR”,它可以使用此url / grade / {id} / edit编辑学校中的任何成绩,使用symfony安全性我可以使它只有具有SCHOOL_DIRECTOR角色的用户才能访问该URL,到目前为止这很好,但是现在我的问题是来自一所学校的SCHOOL_DIRECTOR,如果他在网址中输入正确的ID,则可以从另一所学校编辑成绩。 我正在寻找最好的方法,因为这种情况发生在许多实体上,我知道我总是可以提出加入学校实体的查询,但我担心性能影响,因为我会经常与许多实体进行查询连接。我想知道什么是最好的办法让学校的导演只能获得他们学校的信息。

2 个答案:

答案 0 :(得分:0)

您应该查看symfony voter

示例:

应用/配置/ services.yml

use Symfony\Component\Security\Core\Authorization\Voter\Voter;

class GradeVoter extends Voter
{
    const EDIT     = 'edit';
    const VIEW     = 'view';

    protected function supports($action, $subject)
    {
        if(!$subject instanceof Grade) {
            return false;
        }

        if(!in_array($action, $this->supportedActions())) {
            return false;
        }

        return true;
    }

    protected function voteOnAttribute($action, $grade, TokenInterface $token)
    {
        /** @var Grade $grade */
        switch ($action)
        {
            case self::VIEW:
                return true;
                break;
            case self::EDIT:
                // Do your stuff to return true if the the connected user can edit this grade
                $user = $token->getUser();
                // From the $user variable (which represent the connected user) you have to decide if he can edit this grade, and return true or false. 
                return true;
                break;
            default:
                return false;
        }
    }

    public function supportedActions()
    {
        return [self::EDIT, self::VIEW];
    }
}

<强>的appbundle \安全\选民\ GradeVoter

public function editAction(Grade $grade)
{
    $this->denyAccessUnlessGranted(GradeVoter::EDIT, $grade, 'You can\'t edit this grade');
    // Do your stuff to edit

    return new JsonResponse($response, Response::HTTP_OK);
}

<强> GradeController

$this->denyAccessUnlessGranted(GradeVoter::EDIT, $grade, 'You can\'t edit this grade');

AccessDenied

这一行做了所有的魔术,Symfony将调用你的选民服务并进行上述验证(在这种情况下,编辑开关的情况只是返回true) 如果选民返回false,symfony将抛出PS> perl -i.bak script.pl *.txt 异常,这将在403响应中捕获并完成

我希望我的回答对你有帮助。问我是否有事情不清楚:)

答案 1 :(得分:0)

当您尝试授予特定用户/角色访问特定对象域(学校,成绩,测试......)时,您应该查看ACL

以最简单的方式,acl可以做你想做的事。

希望有所帮助