我有一个symfony2.7应用程序,它有大量的实体,其中许多实体依赖于单个实体,让我举一个例子来澄清
学校有很多学生,学生有很多课,课程有许多测试,测试具有多级
请想象一个类似的数据库设计,但更大,允许许多学校。假设你有一个角色"SCHOOL_DIRECTOR",它可以使用这个url/grade/{id}/edit编辑学校中的任何年级,使用符号安全性,我可以使它成为只有具有SCHOOL_IRECTOR角色的用户才能访问该url,到目前为止还很好,但现在我的问题是,如果一所学校的SCHOOL_DIECTOR在url中输入正确的id,他可以编辑另一所学校中的成绩。我正在寻找最好的方法,因为这种情况发生在许多实体上,我知道我总是可以进行连接回学校实体的查询,但我担心性能会受到影响,因为我会不断地通过许多连接进行查询。我想知道最好的办法是让学校董事只能访问他们学校的信息。
当您试图授予特定用户/角色对特定对象域(学校、年级、测试…)的访问权限时,您应该查看ACL。
在最简单的方式中,acl允许你做你想做的事。
希望它能帮助
您应该看看symfony投票者
示例:
app/config/services.yml
app.security.voter.grade:
class: AppBundleSecurityVoterGradeVoter
tags:
- { name: security.voter }
AppBundle\Security\Voter\GradeVoter
use SymfonyComponentSecurityCoreAuthorizationVoterVoter;
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];
}
}
坡度控制器
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);
}
$this->denyAccessUnlessGranted(GradeVoter::EDIT, $grade, 'You can't edit this grade');
这句话很神奇,Symfony会打电话给你的Voter服务并进行上述验证(在这种情况下,编辑开关的情况只返回true)如果投票者返回false,symfony将抛出一个AccessDenied
异常,该异常将在403响应中被捕获并完成
我希望我的回答对你有帮助。如果有什么不清楚的地方问我:)