0

我正在为使用 FOSFacebookBundle (v2.0) 的 Symfony 2.0 应用程序编写 symfony 功能测试。我正在测试的控制器检查身份验证,如下所示:

if($this->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')){...}

所以我需要对测试的$client(类型Symfony\Bundle\FrameworkBundle\Client)进行身份验证。

假设我需要创建一个有效的令牌并将其设置在$client's security.contextsessioncookieJarfor$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 的安全性。

非常感谢任何评论、指针或资源链接。谢谢!

4

2 回答 2

1

也许最简单的方法是先在 Facebook 上开设一个开发帐户,然后访问开发网站。最重要的是,您会找到工具。其中之一是“令牌调试器”。它可以为您创建令牌。您还可以复制粘贴您通过呼叫获得的令牌之一,该工具将显示令牌的内容。

了解正在发生的事情并查看您获得的令牌是否具有您认为的价值是很有用的。

于 2014-09-03T21:51:34.080 回答
0

问题是 Symfony 2.0 中的一个错误

我注意到$this->contextKeyequals 'primary_auth'inside 方法:\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 (阅读全文))

于 2014-09-05T09:21:26.597 回答