-->

验证在Symfony的2.1功能测试(Authentication in functional te

2019-06-26 05:33发布

我目前在迁移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 \分量\安全\ HTTP \防火墙\ ContextListener”的。 有这样的代码:

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

在我的情况下,如果“$令牌的instanceof AnonymousToken”是真实的,因为会话密钥被删除的。 如果我注释掉的代码一切正常。

所以我想我的新问题是:我能做些什么使令牌不是匿名?

Answer 1:

验证用户正确的方法是:

$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();


Answer 2:

我登录了票上: https://github.com/symfony/symfony/issues/3287

似乎有与Symfony的2.1 RC的现有问题。



Answer 3:

在我的测试套件(工作2.0和2.1现在)我使用扩展的Symfony2 WebTestCase类的基类WebTestCase。

我有一个创建一个匿名客户端或登录一个在我的测试中这两个函数:

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,
    ));
}

然后,在我的测试类,我使用:

    $client = static::createClient();

创建一个匿名客户端和

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

创建一个认证。

这就像在2.1的魅力



Answer 4:

我可以建议另一种解决方案(从而为我工作)。 我有一个自定义身份验证提供商,拥有复杂的逻辑,我不能在所有使用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 }

然后,在测试只是给客户这个网址

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;
}


Answer 5:

我有同样的问题,并找到了解决方案,同时调试。 根据您的会话存储,您可能需要您的Cookie从会话名称()为“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;
}


文章来源: Authentication in functional tests in Symfony 2.1