Я хочу аутентифицировать пользователей через веб-сервис. Я создал брандмауэр, использую Guard и настраиваемого пользователя.
Вот моя проблема: когда я вхожу в систему, пользователь аутентифицируется и сразу выходит из системы после первого перенаправления (web_profiler.intercept_redirects
в true
помогает мне определить это).
Я не знаю, что в моем коде или моей конфигурации может отвечать за это. Я создал аутентификатор, расширяющий AbstractGuardAuthenticator
. В методе checkCredentials()
я вызываю веб-службу, и ответ успешен.
В методе onAuthenticationSuccess()
я устанавливаю токен, предоставленный веб-сервисом в сеансе, и перенаправляю на маршрут, по которому пользователь был до активации аутентификации. Когда перенаправление выполнено, пользователь больше не входит в систему.
Я изучил еще один момент: мой брандмауэр настроен для работы с определенными хостами благодаря ключу host
в конфигурации моего брандмауэра:
customer_account:
pattern: ^(?!/admin[/]*).*$ # all but /admin
host: "%extranet_domain_one%|%extranet_domain_two%"
anonymous: ~
provider: customer_account
form_login:
login_path: customer_account_login
check_path: customer_account_login
guard:
authenticators:
- app.customer_web_service_authenticator
logout:
path: customer_account_logout
target: /
Вот мой access_control
config:
access_control:
- { host: "%extranet_domain_one%|%extranet_domain_two%", path: ^/connexion, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { host: "%extranet_domain_one%|%extranet_domain_two%", path: ^/mot-de-passe, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { host: "%extranet_domain_one%|%extranet_domain_two%", path: ^/, roles: ROLE_CUSTOMER_ACCOUNT }
В моем провайдере метод loadUserByUsername()
возвращает нового пользователя с логином и токеном, хранящимся в сеансе, если он существует.
Любая идея?
Дополнительная информация:
CustomerWebServiceAuthenticator
:
<?php
namespace AppBundle\Security;
use AppBundle\Security\User\CustomerAccount;
use AppBundle\Security\User\CustomerAccountUserProvider;
use AppBundle\Services\Webservice;
use AppBundle\Services\MultisiteHelper;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
/**
* Class CustomerWebServiceAuthenticator
*
* @package AppBundle\Security
*/
class CustomerWebServiceAuthenticator extends AbstractGuardAuthenticator
{
/** @var webservice */
protected $webservice;
/** @var MultisiteHelper */
protected $multisiteHelper;
/** @var \Symfony\Component\Routing\RouterInterface */
protected $router;
/** @var SessionInterface */
protected $session;
/**
* Indique si le site s'exécute en mode développement.
*
* @var boolean
*/
private $dev;
/**
* Default message for authentication failure.
*
* @var string
*/
private $failMessage = 'Mot de passe ou e-mail invalide';
/**
* WebServiceAuthenticator constructor.
*
* @param Webservice $webservice
* @param MultisiteHelper $multisiteHelper
* @param RouterInterface $router
* @param SessionInterface $session
* @param string $kernelEnvironment
*/
public function __construct(
Webservice $webservice,
MultisiteHelper $multisiteHelper,
RouterInterface $router,
SessionInterface $session,
$kernelEnvironment
) {
$this->webservice = $webservice;
$this->multisiteHelper = $multisiteHelper;
$this->router = $router;
$this->session = $session;
$this->dev = $kernelEnvironment === 'dev';
}
/**
* {@inheritdoc}
* @param Request $request
*
* @return array|null
*/
public function getCredentials(Request $request)
{
$url = $request->getRequestUri();
if ($url !== $this->router->generate('customer_account_login') || !$request->isMethod('POST')) {
return null;
}
return [
'username' => $request->request->get('_username'),
'password' => $request->request->get('_password'),
];
}
/**
* {@inheritdoc}
* @param mixed $credentials
* @param UserProviderInterface $userProvider
*
* @return CustomerAccount|null|UserInterface
*/
public function getUser($credentials, UserProviderInterface $userProvider)
{
if (!$userProvider instanceof CustomerAccountUserProvider) {
return null;
}
try {
return $userProvider->loadUserByUsername($credentials['username']);
} catch (UsernameNotFoundException $e) {
throw new CustomUserMessageAuthenticationException($this->failMessage);
}
}
/**
* {@inheritdoc}
* @param mixed $credentials
* @param UserInterface $user
*
* @return bool
*/
public function checkCredentials($credentials, UserInterface $user)
{
$xml = $this->webservice->loginCustomerAccount([
'username' => $credentials['username'],
'password' => ($credentials['password']),
]);
if (isset($xml->identification) && isset($xml->identification['customer_id']) && isset($xml->identification['id_token_session'])) {
/** @var $user CustomerAccount */
$user
->setIdTokenSession((string) $xml->identification['id_token_session'])
->setCustomerId((string) $xml->identification['customer_id'])
;
return true;
}
throw new CustomUserMessageAuthenticationException($this->failMessage);
}
/**
* {@inheritdoc}
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
/** @var $user CustomerAccount */
$user = $token->getUser();
// Stockage en session, c'est ce qui maintient la connexion chez nous
$this->session->clear();
$this->session->set('customer_id', $user->getCustomerId());
$this->session->set('id_token_session_customer', $user->getIdTokenSession());
$this->session->set('login', $user->getUsername());
// @todo LDA : adapter
if ($this->session->has('_security.' . $providerKey . '.target_path')) {
$url = $this->session->get('_security.' . $providerKey . '.target_path');
} else {
$url = $this->router->generate('customer_account_account');
}
return new RedirectResponse($url);
}
/**
* {@inheritdoc}
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
$url = $this->router->generate('customer_account_login');
return new RedirectResponse($url);
}
/**
* {@inheritdoc}
*/
public function start(Request $request, AuthenticationException $authException = null)
{
$url = $this->router->generate('customer_account_login');
return new RedirectResponse($url);
}
/**
* {@inheritdoc}
*/
public function supportsRememberMe()
{
return false;
}
}
onAuthenticationSuccess
? У пользователя уже есть действующий токен аутентификации. - person gp_sflover   schedule 28.04.2017