作为我的Symfony 4应用程序登录/授权过程的一部分,我定义了一个事件侦听器,以确定当前用户可以访问的组组。这会在每个请求上运行:
class DatabaseUserAuthenticationListener {
... //constructor and private vars
public function onKernelController(FilterControllerEvent $event) {
if ($this->authToken && $this->authToken->getUser() !== "anon.") {
$databaseUser = $this->authToken->getUser();
$user = $databaseUser->getUser();
$groups = $this->groupDAO->getUserTree($user);
$privileges = $this->privilegeDAO->getUserPrivileges($user);
$groups->addPrivileges($privileges);
$this->authToken->setAttribute("groupTree", null);
$this->authToken->setAttribute("groupTree", $groups);
}
}
}
已在此处注册为服务:
App\Utility\Security\DatabaseUserAuthenticationListener:
tags:
- { name: kernel.event_listener , event: kernel.controller }
实质上,这是在加载用户有权访问的一组组,然后使用用户可以对每个组执行的特权填充这些组。
这会产生一个GroupTree
对象,看起来像这样:
GroupTree {#444 ▼
#nodeList: array:9 [▶]
#rootNodes: array:2 [▶]
-parents: array:9 [▶]
}
nodeList
显示平面阵列中的整个节点列表。 rootNodes
的所有节点均为树格式。如果我在致电dump($groups)
之前setAttribute
,在nodeList
中会得到类似的信息:
#nodeList: array:9 [▼
14 => GroupNode {#445 ▼
-privileges: array:1 [▼
"VIEW_GROUP" => Privilege {#454 ▶}
]
#nodeId: 14
#nodeObject: Group {#435 ▶}
#children: array:2 [▶]
#parent: null
}
15 => GroupNode {#446 ▶}
...
25 => GroupNode {#453 ▶}
]
这是GroupNode
个对象的平面数组。每个GroupNode
对象都有一个Privilege
对象数组,这些对象代表当前用户可以对Group进行的操作。
我还应该声明该树是通过调用addNode(GroupNode $node)
构建的,因此无法向该树添加除GroupNode之外的其他内容。
这是Weinedness
我有一个ParamConverter
,应该接受控制器传递的ID,并在当前用户的上下文中查找该ID(即,我刚刚放入AuthToken中的GroupTree
),然后返回< em>那个 GroupNode
(具有用户权限)(如果它在树中)。
class GroupConverter implements ParamConverterInterface {
private $groupTree;
public function __construct(TokenStorageInterface $tokenStorage) {
if ($tokenStorage->getToken() instanceof UsernamePasswordToken) {
$token = $tokenStorage->getToken();
//I'm setting the groupTree from the UserToken
$this->groupTree = $token->hasAttribute("groupTree") ? $token->getAttribute("groupTree") : null;
}
}
public function apply(Request $request, ParamConverter $configuration) {
$name = $configuration->getName();
if ($this->groupTree && $this->groupTree->keyExists($request->get("id"))) {
//I'm looking at the id passed in by the controller and using it to look up the GroupNode object in from the tree.
$object = $this->groupTree->getItem($request->get("id"));
} else {
throw new NotFoundHttpException("Group not found!");
}
$request->attributes->set($name, $object);
return true;
}
public function supports(ParamConverter $configuration) {
if ($configuration->getClass() === "App\\Model\\Objects\\GroupNode") {
return true;
}
return false;
}
}
这是一个很奇怪的部分:唯一一次返回GroupNode
对象是当我传入根节点之一时。在所有其他情况下,我会得到一些看似随机的东西...有时是布尔值,有时是字符串,有时是数组。很奇怪。
如果在上面的构造函数中设置好dump($this->groupTree)
之后,这就是我在nodeList
中得到的内容(groupTree
相同):
#nodeList: array:9 [▼
14 => GroupNode {#249 ▶}
15 => "18"
18 => 1
19 => GroupNode {#243 ▶}
20 => "21"
21 => array:2 [▶]
22 => 0
24 => []
25 => 0
]
恰好是14和19(恰好是?)的根源。
因此,总结一下问题:
GroupTree
对象 除了GroupNode
中的nodeList
对象之外,没有其他东西。GroupTree
对象作为属性添加到我的侦听器中的用户身份验证令牌之前对其进行检查,这是正确的。此外,这是设置该属性的 only 位置。但是,每次我在侦听器被调用后从我的GroupConverter
类(大概是)中检查Auth Token上的该属性时,它的格式都是错误的。所以我的问题是广泛而笼统的
是什么原因造成的?做某事明显错了吗?我对这些事情发生的顺序是否正确(真的很重要)吗?
谢谢。