Я делаю REST API для своего приложения, управляемого JS.
Во время входа в систему форма входа выдается через AJAX для URL-адреса /rest/login
в /rest/login
моего API.
Хотя я разделял брандмауэры для API и самого приложения, они имеют один и тот же контекст, который должен означать, что когда пользователь аутентифицируется против API, он также аутентифицируется против приложения. Таким образом, когда сервер вернет 204, страница перезагрузится, и он должен перенаправить пользователя в приложение, потому что он теперь вошел в систему.
Я попытался использовать предварительно check_login
страницу check_login
для FOSUserBundle и указал /rest/login
остался /rest/login
там.
login: path: /rest/login defaults: _controller: FOSUserBundle:Security:check methods: [ POST ]
поlogin: path: /rest/login defaults: _controller: FOSUserBundle:Security:check methods: [ POST ]
Это не работает, потому что он всегда возвращает перенаправление, несмотря ни на что. Я прочитал документацию для symfony и не смог найти, как создать пользовательскую страницу check_login
. Мне нужно что-то вроде этого
use Symfony\Component\Security\Core\Exception\AuthenticationException; use FOS\RestBundle\Controller\Annotations\View; class SecurityController { /** * @View(statusCode=204) */ public function loginAction($username, $password) { /* first I need to somehow authenticate user using normal authentication, that I've set up */ ... /* Then I need to return 204 or throw exception, based on result. This is done using FOSRestBundle and it's listeners. */ if(!$succesful) { throw new AuthenticationException(); } } }
Я не знаю, как это сделать. Ничего, что я нашел в какой-либо документации, немного помогло мне. Я буду благодарен за любое предложение, которое укажет мне в правильном направлении.
EDIT: Чтобы еще больше упростить, к чему я стремлюсь. Я хочу, чтобы мой логин функционировал точно так же, как и обычный form_login . Я только хочу изменить ответ, который он отправляет обратно – вместо перенаправления я хочу 204 на успех и 401 при сбое.
Я смог найти простое решение. Мне нужно было написать класс, который реализует AuthenticationSuccessHandlerInterface
и AuthenticationFailureHandlerInterface
.
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; class AuthenticationRestHandler implements AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface { public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { return new Response('', Response::HTTP_UNAUTHORIZED); } public function onAuthenticationSuccess(Request $request, TokenInterface $token) { return new Response('', Response::HTTP_NO_CONTENT); } }
Затем я зарегистрировал его как услугу и настроил как обработчики для брандмауэра.
services: security.authentication_rest_handler: class: AuthenticationRestHandler security: firewalls: rest: pattern: ^rest context: app form_login: check_path: /rest/login provider: fos_userbundle failure_handler: inspireon.security.authentication_rest_handler success_handler: inspireon.security.authentication_rest_handler username_parameter: login password_parameter: password
Проблема решена и не требуется сложный поставщик аутентификации 🙂
Я понял вашу проблему, потому что я прошел аналогичную ситуацию, но с SOAP-сервисами. В середине я мог повторно искать безопасность wsse, а Symfony2 уже предоставил решение
http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html
Он работает с реальным токеном, и вы можете совпадать с пользователем в FOSUserBundle. Единственное, что я вижу, это поле «пароль», которое вы хотите сравнить, такое же, как в базе данных (с шифрованием), тогда я решил создать дополнительное поле только для этого использования.
Надеюсь, это поможет вам.
Приветствую