19

現在、2.0.* プロジェクトを Symfony の現在の 2.1 ベータ版に移行中です。

私の機能テストでは、現在、認証を使用してクライアントを作成するための次のコードがあります。

$client = // create a normal test client
$role = 'ROLE_USER';
$firewallName = 'main';
$user = // pull a user from db

$client->getCookieJar()->set(new \Symfony\Component\BrowserKit\Cookie(session_name(), true));

$token = new UsernamePasswordToken($user, null, $firewallName, array($role));

self::$kernel->getContainer()->get('session')->set('_security_' . $firewallName, 
serialize($token));

これは 2.0.* では期待どおりに機能しますが、2.1 では機能しません。データはセッションに設定されません。

何か案は?

編集(さらに情報を追加):

問題はメソッド「onKernelResponse 」のファイル「Symfony\Component\Security\Http\Firewall\ContextListener 」にあるようです。このコードがあります:

if ((null === $token = $this->context->getToken()) || ($token instanceof AnonymousToken)) {
    $session->remove('_security_'.$this->contextKey);
} else {
    $session->set('_security_'.$this->contextKey, serialize($token));
}

私の場合、「$token instanceof AnonymousToken」が true の場合、そのためセッション キーが削除されます。そのコードをコメントアウトすると、すべてが期待どおりに機能します。

だから私は私の新しい質問は次のとおりだと思います: トークンを匿名にするにはどうすればよいですか?

4

5 に答える 5

11

ユーザーを認証する適切な方法は次のとおりです。

$firewallName = 'your-firewall-name';
$container = self::$kernel->getContainer()
$token = new UsernamePasswordToken($user, null, $firewallName, $user->getRoles());
$container->get('security.context')->setToken($token);

およびファイアウォール認証:

$session = $container->get('session');
$session->set('_security_'.$firewallName, serialize($token));
$session->save();
于 2012-07-19T09:22:06.967 に答える
1

私は別の解決策を提案することができます(したがって、それは私のために働いています)。複雑なロジックを持つカスタム認証プロバイダーがあり、http_basicメカニズムをまったく使用できません。

このような特別なアクションを作成する必要があります

 //TestAuthController.php
 public function authTestAction(Request $request)
 { 
   // you can add different security checks as you wish
   $user_id = $request->query->get("id");
   // find user  by $user_id using service or user provider service from firewall config
   $token = new UsernamePasswordToken($user, null, $firewallName, array($role));
    // or another authenticated token
   $this->container->get('security.context')->setToken($token);
 }

routing_test.ymlを追加し、routing_dev.ymlと同じようにプラグインします

この認証ルートは、セキュリティ上の理由から、テスト環境にのみ存在する必要があるという重要なことです。

 //app/config/routing_test.yml
 // ... the same routes as in routing_dev.yml
_testauth:
    pattern:  /__test
    defaults: { _controller: MyBundle:TestAuth:authTest }

次に、テストでは、クライアントをこのURLに送信するだけです

public function testSomething()
{
    $client = static::createClient();
    $client->request('GET','/__test',array('id'=>146));
    $this->assertTrue($client->getContainer()->get('security.context')->isGranted('ROLE_USER')) //it will pass;
}
于 2012-09-19T11:59:47.487 に答える
1

私は同じ問題を抱えていて、デバッグ中に解決策を見つけました。セッション ストレージによっては、Cookie を session_name() から 'MOCKSESSID' に変更する必要がある場合があります (これは、モック セッションを使用している場合に使用されます。config_test.yml に次の内容がある場合、自動的にモックに変更されると思います)セッション ストレージ:

framework:
   test: ~

完全を期すために、ここに私の完全なコード (私は FOS/UserBundle を使用しています)

    protected function createAuthorizedClient($username = 'user') {
      $client = $this->createClient(); //Normal WebTestCase client     
      $userProvider = $this->get('fos_user.user_manager');
      $user = $userProvider->loadUserByUsername($username);
      //$client->getCookieJar()->set(new Cookie(session_name(), true));
      $client->getCookieJar()->set(new Cookie('MOCKSESSID', true));
      $session = self::$kernel->getContainer()->get('session');
      $token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
      $client->getContainer()->get('security.context')->setToken($token);
      $session->set('_security_main', serialize($token));

    return $client;
}
于 2012-12-26T19:43:46.197 に答える
1

チケットを記録しました: https://github.com/symfony/symfony/issues/3287

Symfony 2.1 RC には既存の問題があるようです。

于 2012-08-07T11:52:39.083 に答える
1

私のテストスイート (2.0 と現在は 2.1 で作業中) では、Symfony2 の WebTestCase クラスを拡張する Base クラスの WebTestCase を使用しています。

私のテストでは、匿名クライアントまたはログに記録されたクライアントを作成する次の 2 つの関数があります。

static protected function createClient(array $options = array(), array $server = array())
{
    $client = parent::createClient($options, $server);

    self::$container = self::$kernel->getContainer();

    return $client;
}

protected function createAuthClient($user, $pass)
{
    return self::createClient(array(), array(
        'PHP_AUTH_USER' => $user,
        'PHP_AUTH_PW'   => $pass,
    ));
}

次に、私の Test クラスでは、次のものを使用します。

    $client = static::createClient();

anonクライアントを作成し、

    $client = static::createAuthClient('user','pass');

認証済みのものを作成します。

これは2.1で魅力的に機能します

于 2012-08-11T21:13:10.067 に答える