如何通过伪造登录来测试Symfony 2中的ACL

时间:2011-12-10 10:12:09

标签: php authentication symfony

我正在开发一个基于Symfony 2的Web应用程序构建的一部分。就像许多应用程序,身份验证和授权是必需的。如何通过传递或伪造登录来继续开发,考虑ACL?

在文档中,login_check透明地执行身份验证和会话部分。我想我可能需要实现其版本或以某种方式将其称为以不同的用户/角色登录

3 个答案:

答案 0 :(得分:29)

我不完全确定我理解你的问题,但你只是问你如何以编程方式登录?

在我的测试中,我只是做一个如下调用:

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

在这种情况下,“维护”甚至不是真正的用户实体,它只是我为我的灯具制作的用户名,以便他们可以通过ROLE_FIXTURE_LOADER访问服务,但如果您确实想要登录一个完整的用户实体(以便它们具有正确的ACL ID),您可以从数据库中获取$user对象并调用:

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

这不是完全登录,但它确实与RBAC一起工作,如果传递实际的用户对象,我不明白为什么它不适用于ACL。

至于我的前端的功能测试,如果我需要登录,我只需导航到登录页面并按照测试文档提交表单。要使其中任何一个工作,您需要访问容器,因此您需要扩展WebTestCase或推动自己启动内核的能力(请参阅 here )。

我有一种感觉我虽然误解了这个问题(即你需要做一些比放置令牌更复杂的事情)。也许你可以试着澄清一下你的意思

  

传递或伪造登录

在测试中植入安全令牌的具体示例:

首先,我们为要使用的测试创建一个基类,其中包含一个登录便捷方法。这可以通过扩展WebTestCase并在getContainer上使用client方法来完成,或者你可以将WebTestCase分开来滚动你自己的基类,它只引导内核而不需要客户端并返回容器(请参阅我的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.
    }

}

希望这有帮助。

答案 1 :(得分:1)

不确定我是否理解您的问题但是如果您只想查看具有不同用户角色的应用程序,则可以使用此处记录的Symfony Role Switcher: http://symfony.com/doc/current/book/security.html#impersonating-a-user

因此,您只需在网址中添加一个参数即可将您的应用视为另一个连接用户。

希望它有所帮助!

答案 2 :(得分:0)