Я пишу функциональные тесты Symfony для приложения Symfony 2.0, которое использует FOSFacebookBundle (v2.0). Контроллеры, которые я тестирую, проверяют подлинность следующим образом:
if($this->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')){...}
Поэтому мне нужно, чтобы тест $client
(типа Symfony\Bundle\FrameworkBundle\Client
) был аутентифицирован.
Предположительно, мне нужно создать действительный токен и установить его на security.context
, session
и cookieJar
$client
для аутентификации $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.
Этот класс использует php api facebook (класс BaseFacebook) для вызова API-интерфейса facebook (BaseFacebook->api('/me')), но этого никогда не происходит, так как я не могу пройти мимо безопасности Symfony.
Любые комментарии, указатели или ссылки на ресурсы приветствуются. Спасибо!