Symfony 4.0
Этот процесс не изменился с symfony 3 на 4, но вот пример использования недавно рекомендованного AbstractController. Обе службы security.token_storage
и session
службы зарегистрированы в родительском getSubscribedServices
методе, поэтому вам не нужно добавлять их в свой контроллер.
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use YourNameSpace\UserBundle\Entity\User;
class LoginController extends AbstractController{
public function registerAction()
{
$user = //Handle getting or creating the user entity likely with a posted form
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->container->get('security.token_storage')->setToken($token);
$this->container->get('session')->set('_security_main', serialize($token));
// The user is now logged in, you can redirect or do whatever.
}
}
Symfony 2.6.x - Symfony 3.0.x
Symfony 2.6 security.context
устарел в пользу security.token_storage
. Теперь контроллер может быть просто:
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use YourNameSpace\UserBundle\Entity\User;
class LoginController extends Controller{
public function registerAction()
{
$user = //Handle getting or creating the user entity likely with a posted form
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
$this->get('session')->set('_security_main', serialize($token));
}
}
Несмотря на то, что это устарело, вы все равно можете использовать security.context
его, поскольку он был обратно совместим. Просто будьте готовы обновить его для Symfony 3
Подробнее об изменениях в версии 2.6 для обеспечения безопасности можно прочитать здесь: https://github.com/symfony/symfony/blob/2.6/UPGRADE-2.6.md
Symfony 2.3.x
Для этого в Symfony 2.3 вы больше не можете просто установить токен в контексте безопасности. Вам также необходимо сохранить токен в сеансе.
Предполагая файл безопасности с брандмауэром, например:
// app/config/security.yml
security:
firewalls:
main:
//firewall settings here
И действие контроллера тоже похоже:
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use YourNameSpace\UserBundle\Entity\User;
class LoginController extends Controller{
public function registerAction()
{
$user = //Handle getting or creating the user entity likely with a posted form
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.context')->setToken($token);
$this->get('session')->set('_security_main',serialize($token));
//Now you can redirect where ever you need and the user will be logged in
}
}
Для создания токена вы захотите создать. UsernamePasswordToken
Он принимает 4 параметра: объект пользователя, учетные данные пользователя, имя межсетевого экрана, роли пользователей. Вам не нужно предоставлять учетные данные пользователя, чтобы токен был действительным.
Я не уверен на 100%, что установка токена security.context
необходима, если вы собираетесь сразу же перенаправить. Но, похоже, это не больно, поэтому я оставил это.
Затем важная часть - установка переменной сеанса. Переменные именования является _security_
последующим вашим именем брандмауэра, в этом случае main
решений_security_main
$this->get('session')->set('_security_main', serialize($token));
. Спасибо, @Chausser!main
И вы аутентифицируетесь с другим названным брандмауэромadmin
(так как вы выдаете себя за пользователя), происходит странная вещь: он_security_admin
получает сообщениеUsernamePasswordToken
с пользователем, которого вы указали, т.е. вы "отключаетесь" от вашadmin
брандмауэр. Есть идеи, как сохранить токен для брандмауэра «администратора»?setToken(..)
под тем же целевым брандмауэром или еще не прошли аутентификацию .Наконец-то понял это.
После регистрации пользователя у вас должен быть доступ к экземпляру объекта, который вы установили в качестве объекта пользователя в конфигурации вашего провайдера. Решение состоит в том, чтобы создать новый токен с этим пользовательским объектом и передать его в контекст безопасности. Вот пример, основанный на моей настройке:
RegistrationController.php:
Где
main
имя брандмауэра для вашего приложения (спасибо, @Joe). Это действительно все, что нужно сделать; теперь система считает, что ваш пользователь полностью вошел в систему как пользователь, которого они только что создали.РЕДАКТИРОВАТЬ: за комментарий @Miquel, я обновил образец кода контроллера, чтобы включить разумную роль по умолчанию для нового пользователя (хотя, очевидно, это можно настроить в соответствии с конкретными потребностями вашего приложения).
источник
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
Если у вас есть объект UserInterface (а так и должно быть в большинстве случаев), вы можете использовать функцию getRoles, которую он реализует для последнего аргумента. Итак, если вы создадите функцию logUser, она должна выглядеть так:
источник
Я использую Symfony 2.2, и мой опыт немного отличался от опыта Problematic , так что это комбинированная версия всей информации из этого вопроса плюс некоторые из моих собственных.
Я думаю, что Джо ошибается относительно значения
$providerKey
третьего параметраUsernamePasswordToken
конструктора. Это должен быть ключ провайдера аутентификации (а не пользователя). Он используется системой аутентификации, чтобы различать токены, созданные для разных поставщиков. Любой провайдер, являющийся потомком,UserAuthenticationProvider
будет аутентифицировать только токены, ключ провайдера которых совпадает с его собственным. Например,UsernamePasswordFormAuthenticationListener
устанавливает ключ создаваемого токена, совпадающий с соответствующим ключомDaoAuthenticationProvider
. Это позволяет одному брандмауэру иметь несколько провайдеров имени пользователя и пароля, не наступая друг на друга. Поэтому нам нужно выбрать ключ, который не будет конфликтовать с другими поставщиками. Пользуюсь'new_user'
.У меня есть несколько систем в других частях моего приложения, которые зависят от события успешной аутентификации , и это не запускается просто путем установки токена в контексте. Мне пришлось получить
EventDispatcher
из контейнера и запустить событие вручную. Я решил не запускать интерактивное событие входа в систему, потому что мы неявно аутентифицируем пользователя, а не в ответ на явный запрос входа.Обратите внимание, что использование
$this->get( .. )
предполагает, что фрагмент находится в методе контроллера. Если вы используете код где-то еще, вам придется изменить их для вызоваContainerInterface::get( ... )
в соответствии с окружающей средой. Так случилось, что мои пользовательские объекты реализуются,UserInterface
поэтому я могу использовать их напрямую с токеном. Если у вас нет, вам нужно будет найти способ преобразовать их вUserInterface
экземпляры.Этот код работает, но мне кажется, что он взламывает архитектуру аутентификации Symfony, а не работает с ней. Вероятно, было бы правильнее реализовать нового провайдера аутентификации с его собственным классом токенов, а не взламывать
UsernamePasswordToken
. Кроме того, использование подходящего провайдера означало бы, что события обрабатывались за вас.источник
В случае, если у кого-то есть тот же вопрос, который заставил меня вернуться сюда:
призвание
влияет только на ток
security.context
для используемого маршрута.Т.е. вы можете войти в систему только с URL-адреса, находящегося под контролем брандмауэра.
(При необходимости добавьте исключение для маршрута -
IS_AUTHENTICATED_ANONYMOUSLY
)источник
В Symfony 4.4 вы можете просто сделать следующее в своем методе контроллера (см. Документацию Symfony: https://symfony.com/doc/current/security/guard_authentication.html#manually-authenticating-a-user ):
Одна важная вещь: убедитесь, что ваш брандмауэр не включен
lazy
. Если это так, токен никогда не будет сохранен в сеансе, и вы никогда не войдете в систему.источник
Как уже упоминалось здесь Problematic, этот неуловимый параметр $ providerKey на самом деле является не чем иным, как именем вашего правила брандмауэра, 'foobar' в случае примера ниже.
источник
blablabla
качестве третьего параметра в UsernamePasswordToken, она тоже будет работать? что означает этот параметр?Я попробовал все ответы здесь, и ни один из них не сработал. Единственный способ аутентифицировать своих пользователей на контроллере - это сделать подзапрос и затем перенаправить. Вот мой код, я использую silx, но вы можете легко адаптировать его к symfony2:
источник
В Symfony версии 2.8.11 (возможно, работает для более старых и новых версий), если вы используете FOSUserBundle, просто сделайте следующее:
Нет необходимости отправлять событие, как я видел в других решениях.
заимствован из FOS \ UserBundle \ Controller \ RegistrationController :: AuthenticateUser
(из composer.json версии FOSUserBundle: "friendsofsymfony / user-bundle": "~ 1.3")
источник