Как сделать контекст безопасности доступным на странице входа?

В настоящее время я создаю веб-приложение с помощью Silex и только начал внедрять SecurityServiceProvider.

Я добавил следующий фрагмент в код начальной загрузки:

$app->register(new Silex\Provider\SecurityServiceProvider(), array(
    'security.firewalls'    => array(
        'login' => array(
            'pattern' => '^/login$',
            'security' => false,
        ),
        'secured' => array(
            'pattern'   => '^.*$',
            'anonymous' => true,
            'form' => array('login_path' => '/login', 'check_path' => '/login/check'),
            'logout' => array('logout_path', '/logout'),
            'users' => $app['custom.user_provider'],
            'switch_user' => array('parameter' => '_switch_user', 'role' => 'ROLE_IMPERSONATE'),
        ),
    ),
    'security.encoder.digest' => $app->share(function ($app) {
        return new MySQLPasswordEncoder(false);
    }),
));
$app['security.role_hierarchy'] = array(
    'ROLE_ADMIN'    => array('ROLE_STAFF', 'ROLE_BAN_MGR', 'ROLE_IMPERSONATE'),
    'ROLE_STAFF'    => array('ROLE_USER'),
);
$app['security.access_rules'] = array(
    array('^/admin/bans/.*$', 'ROLE_BAN_MGR'),
    array('^/admin/.*$',      'ROLE_STAFF'),
    array('^/account/.*$',    'ROLE_USER'),
    array('^.*$',         ''),
);

Я хочу иметь возможность использовать контекст безопасности (т. е. is_granted(...) в шаблонах) на любой странице, поэтому я использую 'pattern' => '^.*$', 'anonymous' => true.
Чтобы соответствовать требованию, чтобы login_path находился за пределами защищенной области, я добавил брандмауэр login.

Теперь проблема в том, что контекст безопасности недоступен на странице /login, поэтому is_granted(...) выдает исключение:

AuthenticationCredentialsNotFoundException: контекст безопасности не содержит токена проверки подлинности. Одна из возможных причин может заключаться в том, что для этого URL-адреса не настроен брандмауэр.

Я пытался добавить 'security' => true, 'anonymous' => true к брандмауэру login, но это приводит к бесконечным перенаправлениям (поскольку /login находится внутри защищенной зоны).

Вопрос. Как сделать контекст безопасности доступным на странице входа (которая по определению не может быть защищена)?


person Lukas    schedule 07.05.2013    source источник
comment
добавления анонимного => true к маршруту входа должно быть достаточно, чтобы сделать то, что вы хотите.   -  person gunnx    schedule 08.05.2013
comment
@gunnx Я пробовал это как для 'security' => false, так и для 'security' => true, но это не сработало. Ответ mpm преуспевает.   -  person Lukas    schedule 08.05.2013


Ответы (1)


удалить первый брандмауэр

   'login' => array(
            'pattern' => '^/login$',
            'security' => false,
        ),

, это необязательно

и изменить последнее правило доступа на это

array('^/login','IS_AUTHENTICATED_ANONYMOUSLY'),

Подробнее здесь, документация по symfony — это место, где вы должны проводить большую часть своего времени, когда у вас есть вопрос относительно silex:

http://symfony.com/doc/current/book/security.html

person mpm    schedule 08.05.2013
comment
Работает! Спасибо за ссылку - в документации Silex на SecurityServiceProvider это просто гласит: Путь login_path всегда должен быть определен за пределами защищенной области (или, если он находится в защищенной области, должен быть включен механизм анонимной аутентификации - см. ниже );. Объяснения в Symfony Books намного лучше. - person Lukas; 08.05.2013
comment
между silex и symfony есть различия в конфигурации, так что будьте осторожны, но большинство вещей должно работать из коробки, получайте удовольствие! вы можете проверить некоторые из моих скриптов silex здесь: github.com/Mparaiso - person mpm; 08.05.2013