Browse Source

User : connexion

develop
Guillaume 3 years ago
parent
commit
13751bcf89
2 changed files with 83 additions and 114 deletions
  1. +42
    -78
      Authenticator/LoginFormAuthenticator.php
  2. +41
    -36
      Controller/Security/SecurityAdminController.php

+ 42
- 78
Authenticator/LoginFormAuthenticator.php View File



namespace Lc\SovBundle\Authenticator; namespace Lc\SovBundle\Authenticator;


use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Doctrine\EntityManager;
use Lc\SovBundle\Repository\User\UserStore;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\User\UserInterface as SfUserInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait; use Symfony\Component\Security\Http\Util\TargetPathTrait;


class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator
{ {
use TargetPathTrait; use TargetPathTrait;


public const LOGIN_ROUTE = 'sov_login'; public const LOGIN_ROUTE = 'sov_login';


private $entityManager;
private $urlGenerator;
private $csrfTokenManager;
private $passwordEncoder;
protected $parameterBag;
protected UrlGeneratorInterface $urlGenerator;
protected UserStore $userStore;
protected FormFactoryInterface $formFactory;
protected ParameterBagInterface $parameterBag;


public function __construct( public function __construct(
EntityManager $entityManager,
UrlGeneratorInterface $urlGenerator,
CsrfTokenManagerInterface $csrfTokenManager,
UserPasswordEncoderInterface $passwordEncoder,
ParameterBagInterface $parameterBag
)
{
$this->entityManager = $entityManager;
UrlGeneratorInterface $urlGenerator,
UserStore $userStore,
FormFactoryInterface $formFactory,
ParameterBagInterface $parameterBag
) {
$this->urlGenerator = $urlGenerator; $this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
$this->passwordEncoder = $passwordEncoder;
$this->userStore = $userStore;
$this->formFactory = $formFactory;
$this->parameterBag = $parameterBag; $this->parameterBag = $parameterBag;
} }


public function supports(Request $request)
public function supports(Request $request): bool
{ {
return self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
return $request->isMethod('POST') && $this->getLoginUrl($request) === $request->getPathInfo();
} }


public function getCredentials(Request $request)
public function authenticate(Request $request): PassportInterface
{ {
$credentials = [
'email' => $request->request->get('email'),
'password' => $request->request->get('password'),
'csrf_token' => $request->request->get('_csrf_token'),
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['email']
$email = $request->request->get('email');
$password = $request->request->get('password');
$csrfToken = $request->request->get('_csrf_token');

return new Passport(
new UserBadge($email, function ($userIdentifier) {
return $this->userStore->getOneByEmail($userIdentifier);
}),
new PasswordCredentials($password),
[new CsrfTokenBadge('authenticate', $csrfToken)]
); );

return $credentials;
} }


public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}

$user = $this->entityManager->getRepository(UserInterface::class)->findOneBy(
['email' => $credentials['email']]
);

if (!$user) {
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException('Email could not be found.');
}

return $user;
}

public function checkCredentials($credentials, SfUserInterface $user)
{
return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
}

/**
* Used to upgrade (rehash) the user's password automatically over time.
*/
public function getPassword($credentials): ?string
{
return $credentials['password'];
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
{
public function onAuthenticationSuccess(
Request $request,
TokenInterface $token,
string $providerKey
): RedirectResponse {
$routeName = 'home'; $routeName = 'home';
$email = $request->request->get('email'); $email = $request->request->get('email');
$loginRedirection = $this->parameterBag->get('lc_sov.login_redirection'); $loginRedirection = $this->parameterBag->get('lc_sov.login_redirection');
if (isset($useReferer) && $useReferer == true) { if (isset($useReferer) && $useReferer == true) {
$url = $request->request->get('_target_path'); $url = $request->request->get('_target_path');
} else { } else {
$user = $this->entityManager->getRepository(UserInterface::class)->findOneBy(['email' => $email]);
$user = $this->userStore->getOneByEmail($email);


if (!empty($user)) { if (!empty($user)) {
$roles = $user->getRoles(); $roles = $user->getRoles();
} }
} }


protected function getLoginUrl()
protected function getLoginUrl(Request $request): string
{ {
return $this->urlGenerator->generate(self::LOGIN_ROUTE); return $this->urlGenerator->generate(self::LOGIN_ROUTE);
} }
}
}

+ 41
- 36
Controller/Security/SecurityAdminController.php View File

namespace Lc\SovBundle\Controller\Security; namespace Lc\SovBundle\Controller\Security;


use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityAdminController extends AbstractController class SecurityAdminController extends AbstractController
{ {
/** /**
* @Route("/user/login", name="sov_login")
* @Route("/login", name="sov_login")
*/ */
public function login(AuthenticationUtils $authenticationUtils): Response
public function login(AuthenticationUtils $authenticationUtils, Request $request): Response
{ {
if ($this->getUser()) {
return $this->redirectToRoute('app_admin_dashboard');
}
dump($request);

if ($this->getUser()) {
return $this->redirectToRoute('app_admin_dashboard');
}


// get the login error if there is one // get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError(); $error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user // last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername(); $lastUsername = $authenticationUtils->getLastUsername();


return $this->render('@EasyAdmin/page/login.html.twig', [
// parameters usually defined in Symfony login forms
'error' => $error,
'last_username' => $lastUsername,
return $this->render('@EasyAdmin/page/login.html.twig', [
// parameters usually defined in Symfony login forms
'error' => $error,
'last_username' => $lastUsername,


// OPTIONAL parameters to customize the login form:
// OPTIONAL parameters to customize the login form:


// the translation_domain to use (define this option only if you are
// rendering the login template in a regular Symfony controller; when
// rendering it from an EasyAdmin Dashboard this is automatically set to
// the same domain as the rest of the Dashboard)
'translation_domain' => 'admin',
// the translation_domain to use (define this option only if you are
// rendering the login template in a regular Symfony controller; when
// rendering it from an EasyAdmin Dashboard this is automatically set to
// the same domain as the rest of the Dashboard)
'translation_domain' => 'admin',


// the title visible above the login form (define this option only if you are
// rendering the login template in a regular Symfony controller; when rendering
// it from an EasyAdmin Dashboard this is automatically set as the Dashboard title)
'page_title' => '<img src="assets/img/'.$this->get('parameter_bag')->get('app.admin.logo').'" >',
// the title visible above the login form (define this option only if you are
// rendering the login template in a regular Symfony controller; when rendering
// it from an EasyAdmin Dashboard this is automatically set as the Dashboard title)
'page_title' => '<img src="assets/img/' . $this->get('parameter_bag')->get('app.admin.logo') . '" >',


// the string used to generate the CSRF token. If you don't define
// this parameter, the login form won't include a CSRF token
'csrf_token_intention' => 'authenticate',
// the string used to generate the CSRF token. If you don't define
// this parameter, the login form won't include a CSRF token
'csrf_token_intention' => 'authenticate',


// the URL users are redirected to after the login (default: '/admin')
'target_path' => $this->generateUrl('app_admin_dashboard'),
// the URL users are redirected to after the login (default: '/admin')
'target_path' => $this->generateUrl('app_admin_dashboard'),


// the label displayed for the username form field (the |trans filter is applied to it)
'username_label' => 'Your username',
// the label displayed for the username form field (the |trans filter is applied to it)
'username_label' => 'Your username',


// the label displayed for the password form field (the |trans filter is applied to it)
'password_label' => 'Your password',
// the label displayed for the password form field (the |trans filter is applied to it)
'password_label' => 'Your password',


// the label displayed for the Sign In form button (the |trans filter is applied to it)
'sign_in_label' => 'Log in',
// the label displayed for the Sign In form button (the |trans filter is applied to it)
'sign_in_label' => 'Log in',


// the 'name' HTML attribute of the <input> used for the username field (default: '_username')
'username_parameter' => 'email',
// the 'name' HTML attribute of the <input> used for the username field (default: '_username')
'username_parameter' => 'email',


// the 'name' HTML attribute of the <input> used for the password field (default: '_password')
'password_parameter' => 'password',
]);
// the 'name' HTML attribute of the <input> used for the password field (default: '_password')
'password_parameter' => 'password',
]);
} }


/** /**
*/ */
public function logout() public function logout()
{ {
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
throw new \LogicException(
'This method can be blank - it will be intercepted by the logout key on your firewall.'
);
} }
} }

Loading…
Cancel
Save