我有一个带有doctrine的symfony2.7应用程序,它有大量的实体,其中很多实体都依赖于单个实体,让我举一个例子来澄清
学校有很多学生, 学生有很多课, 课程有很多测试, 测试有多个等级
请想象一下像这样的数据库设计,但更大,允许许多学校。假设您有一个角色“SCHOOL_DIRECTOR”,它可以使用此url / grade / {id} / edit编辑学校中的任何成绩,使用symfony安全性我可以使它只有具有SCHOOL_DIRECTOR角色的用户才能访问该URL,到目前为止这很好,但是现在我的问题是来自一所学校的SCHOOL_DIRECTOR,如果他在网址中输入正确的ID,则可以从另一所学校编辑成绩。 我正在寻找最好的方法,因为这种情况发生在许多实体上,我知道我总是可以提出加入学校实体的查询,但我担心性能影响,因为我会经常与许多实体进行查询连接。我想知道什么是最好的办法让学校的导演只能获得他们学校的信息。
答案 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)