2011-12-10 7 views
10

私はSymfony 2上でWebアプリケーションビルドの一部を開発しています。多くのアプリケーションと同様に、認証&の認証が必要です。ログインを偽ったり、偽装したりしてACLを考慮して、どのように開発を続けることができますか?symfony 2でACLをテストするためにログインを偽装する方法

ドキュメントでは、login_checkは、認証とセッションの部分を透過的に処理します。私はそのバージョンを実装するか、何とかなど、さまざまなユーザー/ロール

にログインするためにそれを呼び出す必要があるかもしれませんどちらかだと思う

答えて

29

私は私はあなたの質問を理解し、完全にはよく分からないが、あなただけですあなたがプログラム的にどのようにログインするのか尋ねる?私のテストで

私は単にコールは次のように実行します。このインスタンスのメンテナンス "で

$this->container->get('security.context')->setToken(
    new UsernamePasswordToken(
     'maintenance', null, 'main', array('ROLE_FIXTURE_LOADER') 
    ) 
); 

でも本当のUserエンティティ、私は私の備品用に作られたそのわずかのユーザー名ではありません、彼らができるように、 (彼らは正しいACLのIDを持つように)あなたは、データベースから$userオブジェクトを取得し、呼び出すことができ、完全なユーザエンティティとしてログインしたくなかった場合ROLE_FIXTURE_LOADERを持つことにより、サービスへのアクセスが、:

$this->container->get('security.context')->setToken(
    new UsernamePasswordToken(
     $user, null, 'main', $user->getRoles()) 
    ) 
); 

これは」doesnの完全なログインはしますが、RBACで動作しますd実際のユーザオブジェクトを渡すとACLでうまくいかない理由はわかりません。

フロントエンドの機能テストに関しては、ログインする必要がある場合は、ログインページに移動し、テストドキュメントごとにフォームを送信するだけです。これらのいずれかを動作させるには、コンテナにアクセスする必要がありますので、WebTestCaseを拡張するか、カーネルを起動する独自の機能をロールバックする必要があります(hereを参照)。

質問に間違いがあると感じました(つまり、トークンを置くだけの複雑な操作が必要です)。

まず:おそらく、あなたは

通過またはログインを偽造

テストにセキュリティトークンを植えるための具体的な例で意味をもう少し明確にするために試みることができますログインの便利なメソッドが含まれているテストの基本クラスを作成します。これは、WebTestCaseを拡張し、clientgetContainerメソッドを使用するか、またはWebTestCaseを離れてクライアントを使わずにカーネルを起動し、コンテナを返すだけの独自の基本クラスを作成することができます(これを達成するための2つの解決策についてはlinkを参照してください) 。

namespace Acme\SomeBundle\Tests; 

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; 
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; 

abstract class AcmeTestCase extends WebTestCase { 

    protected function loginAs($client, $username) { 
     $container = $client->getContainer(); 
     $doctrine = $container->get('doctrine'); 

     $user = $this->loadUser($doctrine, $username); 

     // First Parameter is the actual user object. 
     // Change 'main' to whatever your firewall is called in security.yml 
     $container->get('security.context')->setToken(
      new UsernamePasswordToken(
       $user, null, 'main', $user->getRoles() 
      ) 
     ); 
    } 

    private function loadUser($doctrine, $username) { 
     // Don't have to use doctrine if you don't want to, you could use 
     // a service to load your user since you have access to the 
     // container. 

     // Assumes User entity implements UserInterface 
     return $doctrine 
       ->getRepository('AcmeUserBundle:User') 
       ->findOneByUsername($username); 
    } 

} 

次に、任意のテストで基本クラスを使用するだけです。ように:

namespace Acme\SomeBundle\Tests\Entity; 

use Acme\SomeBundle\Tests\AcmeTestCase; 

class SomeEntityTest extends AcmeTestCase { 

    public function somethingTest() { 
     $this->loginAs(static::createClient(), 'SomeUsernameInDB'); 

     // Do the rest of your test here. 
    } 

} 

うまくいけば、これは役立ちます。

+0

私はそれが正しいと思う、私は後でそれを試すことができます。私はちょうど私のACLロジックをテストすることができるようにログインを偽装したいです。 –

+0

うまくいけばそれはあなたを助けるだろう:)。 ACLをテストするには私の2番目のスニペットを使います。最初に '$ user'エンティティを' EntityManager'または 'Repository'から取得し、それを' $ user'としてトークンに渡してください。 – Kasheen

+0

これは実際にテストされたばかりです...私は 'Bottle \ Bundle \ NotesBundle \ Entity \ User"というユーザーのユーザープロバイダは存在しません。私は実際にカスタムFakeUserTokenを作成しましたが、おそらくUsernamePasswordTokenを使用するだけでしたか?私はログインしたユーザーを得ることができる本物のできるだけ近くにいようとしていました。 'UsernamePasswordToken'でどのようにすればいいですか? –

1

私は非常によくあなたの質問を理解していますが、ちょうどあなたがここに文書化されsymfonyの役割スイッチャーを使用することができます別のユーザーの役割とアプリケーションを表示したい場合はわからない: http://symfony.com/doc/current/book/security.html#impersonating-a-user

だから、あなただけでパラメータを配置する必要がありますあなたの別の接続ユーザーとしてあなたのアプリを表示するあなたのURL。

希望すると助かります!

+1

私はこれを信じて、まず管理者としてログインする必要があります –

関連する問題