我不完全确定我理解你的问题,但你只是问你如何以编程方式登录?
在我的测试中,我只需进行如下调用:
$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.
}
}
希望这有帮助。