我忙於在我的應用程序內的Class + Field(classFieldAce)級別實現ACL。似乎一切正常,但我從ACL的isFieldGranted()方法獲得意外的行爲。這裏是我的代碼:Symfony 2 acl isFieldGranted拋出異常
// setup ACL
$className = 'Acme\Model\Junk';
$oid = new ObjectIdentity('class', $className);
try {
$acl = $aclProvider->findAcl($oid);
} catch (Exception $e) {
$acl = $aclProvider->createAcl($oid);
$roleUser = new RoleSecurityIdentity('ROLE_USER');
$mask = new MaskBuilder(4); // 4 = EDIT
$acl->insertclassFieldAce('name', $roleUser, $mask->get());
}
$aclProvider->updateAcl($acl);
迄今爲止好。我將角色「ROLE_USER」分配給我的用戶。現在我想運行一些檢查(手動創建服務)。這裏是檢查代碼(內部控制器現在):
// check the ACL
$className = 'Acme\Model\Junk';
$oid = new ObjectIdentity('class', $className);
$aclProvider = $this->get('security.acl.provider');
try {
$acl = $aclProvider->findAcl($oid);
} catch (...)
都好。現在我想檢查的東西:
$sids = array();
foreach ($this->getUser()->getRoles() as $role) {
$sids[] = new RoleSecurityIdentity($role);
}
$masks = array();
$masks[] = MaskBuilder::MASK_EDIT;
if ($acl->isFieldGranted('name', $masks, $sids)) {
echo "OK";
} else {
echo "NOT ALLOWED";
}
在這一點上一切正常,我得到輸出「OK」。我唯一不確定的是將$ sids發送給支票的非常迂迴的方式 - 所以我的第一個問題是如果除了手動構建列表之外還有更快的方法。
事情剛開始走「錯」(如意外),當我嘗試檢查一個較高的面膜:
$sids = array();
foreach ($this->getUser()->getRoles() as $role) {
$sids[] = new RoleSecurityIdentity($role);
}
$masks = array();
$masks[] = MaskBuilder::MASK_OWNER;
if ($acl->isFieldGranted('name', $masks, $sids)) {
echo "OK";
} else {
echo "NOT ALLOWED";
}
,而不是返回false,$ ACL的> isFieldGranted拋出一個NoAceFoundException。
我是否正在進行野外檢查,或者我應該在這裏找出例外情況?
更新:加入日誌:
校驗碼更改爲:
$this->get('logger')->debug('XX: ACL retrieved, checking field grants');
try {
if ($acl->isFieldGranted('name', $masks, $sids, true)) {
$this->get('logger')->debug('XX: ACL OK for field :name:');
}
} catch (NoAceFoundException $e) {
$this->get('logger')->debug('XX: ACL NOT OK for field :name: NoAceFoundException thrown');
}
當檢查成功,日誌如下:
DEBUG - SELECT o.id as acl_id, o.object_identifier, o.parent_object_identity_id,
o.entries_inheriting, c.class_type, e.id as ace_id, e.object_identity_id, e.field_name,
e.ace_order, e.mask, e.granting, e.granting_strategy, e.audit_success, e.audit_failure,
s.username, s.identifier as security_identifier FROM acl_object_identities o INNER JOIN
acl_classes c ON c.id = o.class_id LEFT JOIN acl_entries e ON (e.class_id = o.class_id AND
(e.object_identity_id = o.id OR e.object_identity_id IS NULL))
LEFT JOIN acl_security_identities s ON (s.id = e.security_identity_id) WHERE (o.id =16)
DEBUG - SELECT t0.name AS name1, t0.roles AS roles2, t0.id AS id3 FROM staff_group t0
INNER JOIN rel_staff_staff_group ON t0.id = rel_staff_staff_group.group_id
WHERE rel_staff_staff_group.staff_id = ? Context: ["242"]
DEBUG - XX: ACL retrieved, checking field grants
DEBUG - XX: ACL OK for field :name:
當檢查失敗,唯一的變化是這條線(我比較了兩個瀏覽器標籤中的日誌)
DEBUG - XX: ACL NOT OK for field :name: NoAceFoundException thrown
有
$acl->isFieldGranted('name', $masks, $sids)
和
$acl->isFieldGranted('name', $masks, $sids, true)
更新2之間的日誌記錄沒有任何區別:
我的Symfony開了一個錯誤報告,它已經解決了https://github.com/symfony/symfony/issues/9433
@freetrace感謝您的建議;更新的問題,但沒有得到太多的日誌 – mogoman
好吧。嘗試在你的'$ acl-> isFieldGranted('name',$ masks,$ sids)''之前插入'var_dump($ acl-> getClassFieldAces('name'));''。 – sergekv
這裏你去http://pastebin.com/RPddrX4P。 – mogoman