1

アプリケーション内のクラス + フィールド (classFieldAce) レベルで ACL を実装するのに忙しいです。すべて正常に動作しているように見えますが、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";
}

$acl->isFieldGranted は false を返すのではなく、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:

チェックが失敗した場合、唯一の変更はこの行です (2 つのブラウザー タブでログを比較しました)

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

4

1 に答える 1