2017-03-06 4 views
0

Symfonyのアクセスコントロールにカスタムアクセス法則を追加する必要があります。私は説明しようとしています。 私はいくつかの顧客とWebアプリケーションを持っており、その顧客が適切なプラグインを持っているときに、コードの一部をアクセスできるようにしたい。プラグインsymfonyセキュリティでダイナミックセキュリティ権限を取得する方法

namespace AppBundle\Entity; 

class Plugin{ 

private $id; 

private $name; 

private $customerProfiles; 
} 

私は彼のプラグインを取得することができ、顧客からのように、私は関係のための教義を使用するための

namespace AppBundle\Entity; 

class CustomerProfile{ 

private $id; 

private $user; 

private $plugins; 
} 

エンティティ:これは私の顧客です。たとえば、私たちは2顧客と2プラグインを持っている:私のプロジェクトで

AppBundle\Entity\CustomerProfile: 
customer_1: 
    user: '@user_1' 
    plugins: ['@plugin_1','@plugin_2'] 
customer_2: 
    user: '@user_2' 
    plugins: ['@plugin_1'] 

AppBundle\Entity\Plugin: 
plugin_1: 
    name: 'plugin 1' 
plugin_2: 
    name: 'plugin 2' 

の顧客に関するすべてのコードは、/顧客の名前空間、symfonyのような、そしてすべての作業中です。別のプラグインと

access_control: 
    - { path: ^/customer, roles: ROLE_CUSTOMER } 

しかし、この顧客のための私は、動のアクセス制御を設定するだろうが、私は方法がわかりません。私はこのような何かを制御する必要があります:

access_control: 
    - { path: ^/code_for_plugin_1, roles: ROLE_CUSTOMER_WHIT_PLUGIN_1} 
    - { path: ^/code_for_plugin_2, roles: ROLE_CUSTOMER_WHIT_PLUGIN_2} 

を、私は良い方法は、その名前空間でのアクセスに役割をプラグイン持っている顧客ごとに設定するには、「サブ役割」(存在する場合)に設定されていると思います。

私は十分に助けてくれてありがとうと思います。

+0

おそらく有権者が必要です。 http://symfony.com/doc/current/security/voters.html –

+0

プラグインに基づいて動的に割り当てられたロールを返すために、単に「CustomerProfile :: getRoles」を実装することもできます。 –

+0

私は既にその文書を読んでいます、私は正しい道が叶うと思います。私は実際には私は5-6のプラグイン(これは将来的には浮かび上がるでしょう)と多くの顧客を持っているので、getRolesのログインは良くないと思うので、私はそれぞれの組み合わせに対して異なるROLEを作成したくありませんプラグイン、それは醜く効率的ではないでしょう。 – NicolaPez

答えて

1

私は、access_controlではなく、カスタムの投票者を使用することをお勧めします。 としてロールのアプローチを使用しています。提案されたソリューションでは、すべてのプラグインに対して の生成ロール(ROLE_CUSTOMER_WHIT_PLUGIN_{X})が必要です。プラグインを動的に追加する場合は、 が機能しません。

詳細については、symfonyのドキュメントのHow to Use Voters to Check User Permissionsの記事を参照してください。

基本的には、ログインしたユーザーが要求されたリソースへのアクセスが であるかどうかをチェックするユーザー有権者を実装する必要があります。あなたのケースでは、次のようになります。

<?php 

... 

class YourController extends Controller 
{ 

    public function getFooAction($id) 
    { 
     $this->denyAccessUnlessGranted(YourVoter::VIEW_FOO); 

     // ...method logic 
    } 

    public function getBarAction($id) 
    { 
     $this->denyAccessUnlessGranted(YourVoter::VIEW_BAR); 

     // ...method logic 
    } 
} 

/src/YourBundle/Security/YourVoter.php

<?php 

... 

class YourVoter extends AbstractVoter 
{ 
    const VIEW_FOO = 'YOUR_VIEW_FOO'; 
    const VIEW_BAR = 'YOUR_VIEW_BAR'; 

    public function getVoterAttributes() 
    { 
     return [self::VIEW_FOO, self::VIEW_BAR,]; 
    } 

    protected function supports($attribute, $subject) 
    { 
     ... 
    } 

    protected function voteOnAttribute($attribute, $item, TokenInterface $token) 
    { 
     $user = $token->getUser(); 
     if (!$user instanceof User) { 
      return false; 
     } 

     switch ($attribute) { 
      case self::VIEW_FOO: 
       return $this->canViewFoo($user); 
      case self::VIEW_BAR: 
       return $this->canViewBar($user); 
     } 

     throw new \Exception(sprintf(
      'Invalid vote attribute "%s".', 
      $attribute 
     )); 
    } 

    private function canViewFoo(User $user) 
    { 
     return $user->getProfile()->hasRoleFooXYZ() 
    } 


    private function canViewBar(User $user) 
    { 
     return $user->getProfile()->hasRoleBarXYZ() 
    } 
} 

/src/YourBundle/Controller/YourController.php

+0

ありがとう、私はあなたの答えとドキュメント(私はすでに読んでいる)を読んで、私は1つの疑問がある:私は投票者がどのように動作するか知っていると思う:それはユーザーから自分のエンティティ(単純なクラス)論理。私のプラグインは顧客が行うことができるアクションのグループですが、mi構造を変更します。各プラグインの指定クラスに戻ることができます。だから、私は各行動で有権者に電話しなければなりませんか?私のことを忘れた場合、私のセキュリティは侵害されますか?この投票者は、そのクラスのすべての行動をクラスで呼び出すのではありませんか?これは非常に便利です。 – NicolaPez

+0

また、私は両方のコントロールを使用すると思います:ルート上の役割とクラス上の有権者と。しかし、私はよく知るために、より深く有権者を勉強しなければなりません。 – NicolaPez

+0

はい、アクセス可能なすべての操作にはセキュリティチェックが必要です。 '$ this-> denyAccessUnlessGranted()'や '$ this-> isGranted()'メソッドを使ってパーミッションをチェックする必要があります。前述のように、両方のアクセスコントロールを組み合わせることもできます。 –

関連する問題