6

アクセス制御リストが Symfony2 に実装されている方法に少し当惑しています。

Zend Framework (バージョン 1 および 2) では、リソースのリストとロールのリストが定義され、各ロールにはアクセスが許可されているリソースのサブセットが割り当てられます。したがって、リソースとロールは ACL 実装の主要なボキャブラリです。これは、ロールのみが支配する Symfony2 には当てはまりません。

レガシー アプリ データベースには、ロールのリスト、リソースのリスト、および各ロールに許可されたリソースのリスト (多対多の関係) を定義するテーブルがあります。各ユーザーには役割 (管理者、スーパー管理者、編集者など) が割り当てられます。

このデータベースを Symfony2 アプリケーションで利用する必要があります。私のリソースは次のようになります: ARTICLE_EDIT、ARTICLE_WRITE、COMMENT_EDIT など。

UserSymfony の私のエンティティはSymfony\Component\Security\Core\User\UserInterfaceインターフェースを実装しているため、getRoles)メソッドがあります。

このメソッドを使用して、許可されるリソースを定義するつもりです。つまり、ロールをリソースとして使用します (つまり、Zend Framework でリソースと呼ばれるものは、ここではロールと呼ばれます)。

この方法を使用する必要があることを確認しますか?

これは、各ユーザーの役割 (管理者、編集者など) を気にする必要がなくなり、そのリソースだけを気にするようになったことを意味します。

$this->get('security.context')->isGranted('ROLE_ARTICLE_WRITE')次に、コントローラーで使用します。

これは正しい方法であり、Symfony でロールを使用するための回避された方法ではないでしょうか?

4

2 に答える 2

2

数年後にこの質問に答えるには、かなり簡単に解決できました。

解決策は、役割とリソースの概念を混合することです。

roleテーブル、resourceテーブル、およびrole_resource多対多の関係が定義されていると仮定しましょう。

ユーザーはuserテーブルに格納されます。

対応する Doctrine エンティティは次のとおりです。

ユーザー:

use Symfony\Component\Security\Core\User\UserInterface;

class User implements UserInterface
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    private $id;

    /**
     * @ManyToOne(targetEntity="Role")
     * @JoinColumn(name="role_id", referencedColumnName="id")
     **/
    private $role;

    // ...
}

役割:

class Role
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    private $id;

    /** @Column(type="string") */
    private $name;

    /**
     * @ManyToMany(targetEntity="Resource")
     * @JoinTable(name="role_resource",
     *      joinColumns={@JoinColumn(name="role_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="resource_id", referencedColumnName="id")}
     *      )
     **/
    private $resources;

    // ...
}

リソース:

class Resource
{
    /**
     * @Id @Column(type="integer")
     * @GeneratedValue
     */
    private $id;

    /** @Column(type="string") */
    private $name;

    // ...
}

したがって、解決策は次getRolesのように実装することですUserInterface

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Role\Role;

class User implements UserInterface
{
    // ...

    /**
     * @var Role[]
     **/
    private $roles;

    /**
     * {@inheritDoc}
     */
    public function getRoles()
    {
        if (isset($this->roles)) {
            return $this->roles;
        }

        $this->roles = array();

        $userRole = $this->getRole();

        $resources = $userRole->getResources();

        foreach ($resources as $resource) {
            $this->roles[] = new Role('ROLE_' . $resource);
        }

        return $this->roles;
    }

}

このようにして、現在のユーザーに起因するリソースを次のように確認できます (名前が のリソースがあることを考慮してARTICLE_WRITEください)。

$this->get('security.context')->isGranted('ROLE_ARTICLE_WRITE')
于 2014-10-27T15:26:54.907 に答える