Symfony2 测试中的伪造身份验证 - 控制器上的 get('security.context')->getToken() 返回的令牌与 TestCase 中设置的令牌不同
Posted
技术标签:
【中文标题】Symfony2 测试中的伪造身份验证 - 控制器上的 get(\'security.context\')->getToken() 返回的令牌与 TestCase 中设置的令牌不同【英文标题】:Faking authentication on Symfony2 tests - get('security.context')->getToken() on Controller returns differnt token than the one set up in the TestCaseSymfony2 测试中的伪造身份验证 - 控制器上的 get('security.context')->getToken() 返回的令牌与 TestCase 中设置的令牌不同 【发布时间】:2014-09-03 21:45:18 【问题描述】:我正在为使用 FOSFacebookBundle (v2.0) 的 Symfony 2.0 应用程序编写 symfony 功能测试。我正在测试的控制器像这样检查身份验证:
if($this->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY'))...
所以我需要对测试的$client
(Symfony\Bundle\FrameworkBundle\Client
类型)进行身份验证。
假设我需要创建一个有效的令牌并将其设置在$client
的security.context
、session
和cookieJar
上,以便对$client
进行身份验证,对吧?
问题是控制器中的security.context
返回的令牌与我在测试的$client
上设置的有效令牌不同。
有谁知道为什么在发出请求后令牌会被重置?
这是我在测试用例类中的设置方式:
use FOS\FacebookBundle\Security\Authentication\Provider\FacebookProvider;
use FOS\FacebookBundle\Security\Authentication\Token\FacebookUserToken;
use Symfony\Component\BrowserKit\Cookie;
$providerKey = 'public';
$facebookMock = $this->getMockBuilder('\Facebook')
->disableOriginalConstructor()
->getMock();
$facebookMock->expects($this->once())
->method('getUser')
->will($this->returnValue('DevTestUsername'));
$facebookProvider = new FacebookProvider($providerKey, $facebookMock);
$tokenMock = new FacebookUserToken(
'public',
'DevTestUsername',
array('ROLE_MEMBER', 'ROLE_MANAGER', 'ROLE_USER')
);
$authenticatedToken = $facebookProvider->authenticate($tokenMock);
$client->getContainer()->get('security.context')->setToken($authenticatedToken);
$client->getContainer()->get('session')->set('_security_public', serialize($authenticatedToken));
$client->getContainer()->get('session')->save();
$client->getCookieJar()->set(new Cookie(session_name(), $client->getContainer()->get('session')->getId()));
设置完成后,在测试用例中返回true
:
if($client->getContainer()->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY'))...
但在控制器上,它返回false
if($this->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY'))...
我是否在 security.context 或会话中设置错误?
这是应用程序的安全配置:
security:
factories:
- "%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml"
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: [ROLE_USER, ROLE_ALLOWED_TO_SWITCH]
ROLE_SUPER_ADMIN: [ROLE_ADMIN]
providers:
chain_provider:
providers: [fos_userbundle, facebook_provider]
fos_userbundle:
id: fos_user.user_manager
facebook_provider:
id: facebook.user
firewalls:
public:
pattern: ^/.*
fos_facebook:
provider: facebook_provider
app_url: "http://apps.facebook.com/myapp"
server_url: "http://myapp.local/"
login_path: /login
check_path: /login_check
default_target_path: /target
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
login_path: /login
check_path: /login_check
anonymous: true
switch_user: role: ROLE_ADMIN
logout:
target: http://myapp.com
handlers: ["fos_facebook.logout_handler"]
context: primary_auth
facebook.id 服务是一个实现 Symfony\Component\Security\Core\User\UserProviderInterface 的类
这个类使用 facebook 的 php api(BaseFacebook 类)来调用 facebook graph api(BaseFacebook->api('/me')),但这永远不会发生,因为我没有通过 Symfony 的安全性。
非常感谢任何 cmets、指针或资源链接。谢谢!
【问题讨论】:
【参考方案1】:也许最简单的方法是先在 Facebook 上开设一个开发帐户,然后访问开发网站。最重要的是,您会找到工具。其中之一是“令牌调试器”。它可以为您创建令牌。您还可以复制粘贴您通过调用获得的令牌之一,该工具将显示令牌的内容。
了解正在发生的事情并查看您获得的令牌是否具有您认为的价值非常有用。
【讨论】:
感谢您的评论,但这不是 FB 代币。问题是我没有通过 Symfony 的安全层。我确实检查了 FB 的令牌调试器,很高兴知道:)【参考方案2】:问题是 Symfony 2.0 中的一个错误
我注意到 $this->contextKey
等于 'primary_auth'
内部方法:\Symfony\Component\Security\Http\Firewall\ContextListener::handle(GetResponseEvent $event)
所以在我的测试套件中我会这样做:
$client->getContainer()->get('session')->set('_security_primary_auth', serialize($authenticatedToken));
而不是
$client->getContainer()->get('session')->set('_security_public', serialize($authenticatedToken));
(这里记录了这个问题:https://github.com/symfony/symfony/issues/5228(阅读全文))
【讨论】:
以上是关于Symfony2 测试中的伪造身份验证 - 控制器上的 get('security.context')->getToken() 返回的令牌与 TestCase 中设置的令牌不同的主要内容,如果未能解决你的问题,请参考以下文章
Symfony2 - 将安全访问控制设置为只允许匿名身份验证