5

いくつかのACL権限を必要とするSymfony2アプリケーションで忙しいです。

私はSymfony2の初心者なので、これを正しい方法で見ているのかどうかわかりません。

私には複数のクライアントがあり、それぞれに複数のアカウントがあります。

すべてのクライアントとすべてのアカウントにアクセスできるスーパー管理者(ROLE_SUPER_ADMIN)がいます。次に、管理者ロール(ROLE_ADMIN)があります。このロールは、特定のクライアントとそのクライアントのすべてのアカウントへのアクセスのみを許可されます。次に、エージェント(ROLE_AGENT)があります。これは、クライアントの特定のアカウントに対する権限のみを持つ必要があります。

symfonyのドキュメントで、ユーザーに特定のオブジェクトへのアクセスを許可するために、次のコードを使用できることを確認しました。

// creating the ACL
$aclProvider = $this->get('security.acl.provider');
$objectIdentity = ObjectIdentity::fromDomainObject($account);
$acl = $aclProvider->createAcl($objectIdentity);

// retrieving the security identity of the currently logged-in user
$securityContext = $this->get('security.context');
$user = $securityContext->getToken()->getUser();
$securityIdentity = UserSecurityIdentity::fromAccount($user);

// grant owner access    
$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER);
$aclProvider->updateAcl($acl);

したがって、新しいアカウントを作成するときに、現在ログインしているユーザーに、新しく作成したアカウントへのアクセスを許可できます。しかし、クライアントの他のすべてのユーザーにアカウントへのアクセスを許可するにはどうすればよいですか?

すべてのユーザーをループして、すべてのユーザーに対して上記のコードを実行したくありません。

したがって、たとえば、すべてのクライアントを表示するときは、ユーザーがアクセスできるクライアントを知る必要があります。アカウントを表示するときは、ユーザーがアクセスできるアカウントを知る必要があります。

また、新しいユーザーをクライアントに追加する場合、ユーザーは自動的にそのクライアントのすべてのアカウントにアクセスできる必要があります。

ちなみに、ユーザーがアカウント/クライアントにアクセスできるかどうかだけを知る必要があります。ユーザーがアクセス権を持っている場合、ユーザーは自動的に表示/編集/削除などを許可されます。

4

1 に答える 1

0

この場合、エンティティ間の多対多の関係を検証するカスタム セキュリティ サービスを使用しました。これは理想的な決定ではありませんが、心に留めておいてください。

最初に、すべてのコントローラー アクションでトリガーされるリスナーを作成する必要があります。

class SecurityListener
{
    protected $appSecurity;

    function __construct(AppSecurity $appSecurity)
    {
        $this->appSecurity = $appSecurity;
    }

    public function onKernelController(FilterControllerEvent $event)
    {
        $c = $event->getController();

        /*
         * $controller passed can be either a class or a Closure. This is not usual in Symfony2 but it may happen.
         * If it is a class, it comes in array format
         */
        if (!is_array($c)) {
            return;
        }

        $hasAccess = $this->appSecurity->hasAccessToContoller($c[0], $c[1], $event->getRequest());

        if(!$hasAccess) {
            throw new AccessDeniedHttpException('Access denied.');
        }

    }
}

サービスでは、リクエスト、コントローラー インスタンス、および呼び出されたアクションにアクセスできます。したがって、ユーザーアクセスを許可するかどうかを決定できます。

class AppSecurity
{
    protected $em;
    protected $security;
    /** @var $user User */
    protected $user;

    public function __construct(EntityManager $em, SecurityContext $security)
    {
        $this->em = $em;
        $this->security = $security;

        if($security->getToken() !== null && !$security->getToken() instanceof AnonymousToken) {
            $this->user = $security->getToken()->getUser();
        }
    }

    /**
     * @param $controller
     * @param string $action
     */
    public function hasAccessToContoller($controller, $action, Request $request)
    {
        $attrs = $request->attributes->all();
        $client = $attrs['client'];

        /* db query to check link between logged user and request client */
    }
}

非常に厄介なアノテーションParamConverterを使用している場合は、リクエストからすぐに使用できるエンティティを簡単に抽出できます。

于 2013-08-09T10:31:58.733 に答える