Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Guard: o poder da autenticação do Symfony Security

Guard: o poder da autenticação do Symfony Security

Existem muitas maneiras interessantes de autenticar um usuário: API token, social login, um formulário HTML tradicional ou qualquer outra coisa que você possa imaginar.

Mas criar um sistema de autenticação personalizado no Symfony costumava significar muitos arquivos, muito código e muita complexidade. Agora, não mais.

Symfony Guard: um sistema de autenticação simples, mas expansível, parte do componente Symfony Security. Com poucas classes conseguimos implementar autenticação por API token, social login ou até mesmo integrar com algum sistema de autenticação legado.

Não significa que não teremos trabalho algum de implementação, mas o que teremos vai ser mais claro, simples e divertido.

Diana Arnos

May 17, 2019
Tweet

More Decks by Diana Arnos

Other Decks in Programming

Transcript

  1. @dianaarnos Dev, Sec, Music, Kung Fu. Dev / Architect @

    Senha Segura Evangelist @ PHPSP Evangelist @ PHPWomenBR
  2. namespace Symfony\Component\Security\Core\User; /*...*/ interface UserInterface { public function getRoles(); public

    function getPassword(); public function getSalt(); public function getUsername(); public function eraseCredentials(); } USER INTERFACE
  3. namespace Symfony\Component\Security\Core\User; /*...*/ interface UserInterface { public function getRoles(); public

    function getPassword(); public function getSalt(); public function getUsername(); public function eraseCredentials(); } USER INTERFACE
  4. What style of authentication do you want? [Empty authenticator ]:

    [0] Empty authenticator [1] Login form authenticator > 1 The class name of the authenticator to create (e.g. AppCustomAuthenticator ): > LoginFormAuthenticator Choose a name for the controller class (e.g. SecurityController ) [SecurityController ]: >
  5. CONTROLLER namespace App\Controller; /*...*/ class SecurityController extends AbstractController { /**

    * @Route("/login", name="app_login") */ public function login(AuthenticationUtils $authenticationUtils) { return $this->render('security/login.html.twig'); } }
  6. CONTROLLER namespace App\Controller; /*...*/ class SecurityController extends AbstractController { /**

    * @Route("/login", name="app_login") */ public function login(AuthenticationUtils $authenticationUtils) { return $this->render('security/login.html.twig'); } }
  7. CONTROLLER namespace App\Controller; /*...*/ class SecurityController extends AbstractController { /**

    * @Route("/login", name="app_login") */ public function login(AuthenticationUtils $authenticationUtils) { return $this->render('security/login.html.twig'); } }
  8. FORM <form class="form-signin" method="post"> {% if error %} <div class="alert

    alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div> {% endif %} <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1> <label for="inputEmail" class="sr-only">Email address</label> <input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required> <button class="btn btn-lg btn-primary btn-block" type="submit"> Sign in </button> </form>
  9. namespace Symfony\Component\Security\Guard; /*...*/ interface AuthenticatorInterface extends AuthenticationEntryPointInterface { public function

    supports(Request $request); public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function supportsRememberMe(); } AUTHENTICATOR INTERFACE
  10. namespace Symfony\Component\Security\Guard; /*...*/ interface AuthenticatorInterface extends AuthenticationEntryPointInterface { public function

    supports(Request $request); public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function supportsRememberMe(); } AUTHENTICATOR INTERFACE
  11. namespace Symfony\Component\Security\Guard; /*...*/ interface AuthenticatorInterface extends AuthenticationEntryPointInterface { public function

    supports(Request $request); public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function supportsRememberMe(); } AUTHENTICATOR INTERFACE
  12. namespace Symfony\Component\Security\Guard; /*...*/ interface AuthenticatorInterface extends AuthenticationEntryPointInterface { public function

    supports(Request $request); public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function supportsRememberMe(); } AUTHENTICATOR INTERFACE
  13. namespace Symfony\Component\Security\Guard; /*...*/ interface AuthenticatorInterface extends AuthenticationEntryPointInterface { public function

    supports(Request $request); public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function supportsRememberMe(); } AUTHENTICATOR INTERFACE
  14. namespace Symfony\Component\Security\Guard; /*...*/ interface AuthenticatorInterface extends AuthenticationEntryPointInterface { public function

    supports(Request $request); public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function supportsRememberMe(); } AUTHENTICATOR INTERFACE
  15. namespace Symfony\Component\Security\Guard; /*...*/ interface AuthenticatorInterface extends AuthenticationEntryPointInterface { public function

    supports(Request $request); public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function supportsRememberMe(); } AUTHENTICATOR INTERFACE
  16. namespace Symfony\Component\Security\Guard; /*...*/ interface AuthenticatorInterface extends AuthenticationEntryPointInterface { public function

    supports(Request $request); public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function supportsRememberMe(); } AUTHENTICATOR INTERFACE
  17. namespace Symfony\Component\Security\Guard; /*...*/ interface AuthenticatorInterface extends AuthenticationEntryPointInterface { public function

    supports(Request $request); public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function supportsRememberMe(); } AUTHENTICATOR INTERFACE
  18. namespace Symfony\Component\Security\Guard; /*...*/ interface AuthenticatorInterface extends AuthenticationEntryPointInterface { public function

    supports(Request $request); public function getCredentials(Request $request); public function getUser($credentials, UserProviderInterface $userProvider); public function checkCredentials($credentials, UserInterface $user); public function createAuthenticatedToken(UserInterface $user, $providerKey); public function onAuthenticationFailure(Request $request, AuthenticationException $exception); public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey); public function supportsRememberMe(); } AUTHENTICATOR INTERFACE
  19. security: encoders: App\Entity\User: algorithm: argon2i #bcrypt providers: app_user_provider: entity: class:

    App\Entity\User property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: true guard: authenticators: - App\Security\LoginFormAuthenticator entry_point: App\Security\LoginFormAuthenticator SECURITY.YAML
  20. security: encoders: App\Entity\User: algorithm: argon2i #bcrypt providers: app_user_provider: entity: class:

    App\Entity\User property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: true guard: authenticators: - App\Security\LoginFormAuthenticator entry_point: App\Security\LoginFormAuthenticator SECURITY.YAML
  21. security: encoders: App\Entity\User: algorithm: argon2i #bcrypt providers: app_user_provider: entity: class:

    App\Entity\User property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: true guard: authenticators: - App\Security\LoginFormAuthenticator entry_point: App\Security\LoginFormAuthenticator SECURITY.YAML
  22. security: encoders: App\Entity\User: algorithm: argon2i #bcrypt providers: app_user_provider: entity: class:

    App\Entity\User property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: true guard: authenticators: - App\Security\LoginFormAuthenticator entry_point: App\Security\LoginFormAuthenticator SECURITY.YAML
  23. security: encoders: App\Entity\User: algorithm: argon2i #bcrypt providers: app_user_provider: entity: class:

    App\Entity\User property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: true guard: authenticators: - App\Security\LoginFormAuthenticator entry_point: App\Security\LoginFormAuthenticator SECURITY.YAML
  24. security: encoders: App\Entity\User: algorithm: argon2i #bcrypt providers: app_user_provider: entity: class:

    App\Entity\User property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: true guard: authenticators: - App\Security\LoginFormAuthenticator entry_point: App\Security\LoginFormAuthenticator SECURITY.YAML
  25. CONTROLLER namespace App\Controller; /*...*/ class SecurityController extends AbstractController { /**

    * @Route("/login", name="app_login") */ public function login(AuthenticationUtils $authenticationUtils) { return $this->render('security/login.html.twig'); } }
  26. LOGIN FORM AUTHENTICATOR public function getCredentials (Request $request) { $credentials

    = [ 'email' => $request->request->get( 'email'), 'password' => $request->request->get( 'password'), ]; return $credentials; }
  27. LOGIN FORM AUTHENTICATOR public function getCredentials (Request $request) { $credentials

    = [ 'email' => $request->request->get( 'email'), 'password' => $request->request->get( 'password'), ]; return $credentials; }
  28. LOGIN FORM AUTHENTICATOR public function getUser($credentials, UserProviderInterface $userProvider) { return

    $this->userRepository->findOneBy(['email' => $credentials['email']]); }
  29. LOGIN FORM AUTHENTICATOR public function getUser($credentials, UserProviderInterface $userProvider) { return

    $this->userRepository->findOneBy(['email' => $credentials['email']]); }
  30. LOGIN FORM AUTHENTICATOR public function getUser($credentials, UserProviderInterface $userProvider) { return

    $this->userRepository->findOneBy(['email' => $credentials['email']]); } public function checkCredentials($credentials, UserInterface $user) { return $this->passwordEncoder->isPasswordValid($user, $credentials['password']); }
  31. LOGIN FORM AUTHENTICATOR public function getUser($credentials, UserProviderInterface $userProvider) { return

    $this->userRepository->findOneBy(['email' => $credentials['email']]); } public function checkCredentials($credentials, UserInterface $user) { return $this->passwordEncoder->isPasswordValid($user, $credentials['password']); }
  32. LOGIN FORM AUTHENTICATOR public function onAuthenticationSuccess(Request $request, $providerKey) { if

    ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) { return new RedirectResponse($targetPath); } return new RedirectResponse($this->router->generate('app_homepage')); }
  33. LOGIN FORM AUTHENTICATOR public function onAuthenticationSuccess(Request $request, $providerKey) { if

    ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) { return new RedirectResponse($targetPath); } return new RedirectResponse($this->router->generate('app_homepage')); } public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { if ($request->hasSession()) { $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception); } $url = $this->getLoginUrl(); return new RedirectResponse($url); }
  34. LOGIN FORM AUTHENTICATOR public function onAuthenticationSuccess(Request $request, $providerKey) { if

    ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) { return new RedirectResponse($targetPath); } return new RedirectResponse($this->router->generate('app_homepage')); } public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { if ($request->hasSession()) { $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception); } $url = $this->getLoginUrl(); return new RedirectResponse($url); }
  35. FORM CSRF <form class="form-signin" method="post"> {% if error %} <div

    class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div> {% endif %} <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1> <label for="inputEmail" class="sr-only">Email address</label> <input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required> <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}"> </form>
  36. FORM CSRF <form class="form-signin" method="post"> {% if error %} <div

    class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div> {% endif %} <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1> <label for="inputEmail" class="sr-only">Email address</label> <input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required> <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}"> </form>
  37. FORM CSRF <form class="form-signin" method="post"> {% if error %} <div

    class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div> {% endif %} <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1> <label for="inputEmail" class="sr-only">Email address</label> <input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" name="password" id="inputPassword" class="form-control" placeholder="Password" required> <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}"> </form>
  38. LOGIN FORM AUTHENTICATOR CSRF public function getCredentials(Request $request) { $credentials

    = [ 'email' => $request->request->get('email'), 'password' => $request->request->get('password'), 'csrf_token' => $request->request->get('_csrf_token'), ]; return $credentials; }
  39. LOGIN FORM AUTHENTICATOR CSRF public function getCredentials(Request $request) { $credentials

    = [ 'email' => $request->request->get('email'), 'password' => $request->request->get('password'), 'csrf_token' => $request->request->get('_csrf_token'), ]; return $credentials; }
  40. LOGIN FORM AUTHENTICATOR CSRF O TOKEN É VÁLIDO? public function

    checkCredentials($credentials, UserInterface $user) { }
  41. LOGIN FORM AUTHENTICATOR CSRF O TOKEN É VÁLIDO? public function

    checkCredentials($credentials, UserInterface $user) { } public function getUser($credentials, UserProviderInterface $userProvider) { $token = new CsrfToken('authenticate', $credentials['csrf_token']); if (!$this->csrfTokenManager->isTokenValid($token)) { throw new InvalidCsrfTokenException(); } return $this->userRepository->findOneBy(['email' => $credentials['email']]); }
  42. LOGIN FORM AUTHENTICATOR CSRF O TOKEN É VÁLIDO? public function

    checkCredentials($credentials, UserInterface $user) { } public function getUser($credentials, UserProviderInterface $userProvider) { $token = new CsrfToken('authenticate', $credentials['csrf_token']); if (!$this->csrfTokenManager->isTokenValid($token)) { throw new InvalidCsrfTokenException(); } return $this->userRepository->findOneBy(['email' => $credentials['email']]); }
  43. LOGIN FORM AUTHENTICATOR CSRF O TOKEN É VÁLIDO? public function

    checkCredentials($credentials, UserInterface $user) { } public function getUser($credentials, UserProviderInterface $userProvider) { $token = new CsrfToken('authenticate', $credentials['csrf_token']); if (!$this->csrfTokenManager->isTokenValid($token)) { throw new InvalidCsrfTokenException(); } return $this->userRepository->findOneBy(['email' => $credentials['email']]); }
  44. LOGIN FORM AUTHENTICATOR CSRF O TOKEN É VÁLIDO? public function

    getUser($credentials, UserProviderInterface $userProvider) { $token = new CsrfToken('authenticate', $credentials['csrf_token']); if (!$this->csrfTokenManager->isTokenValid($token)) { throw new InvalidCsrfTokenException(); } return $this->userRepository->findOneBy(['email' => $credentials['email']]); }
  45. LOGIN FORM AUTHENTICATOR CSRF O TOKEN É VÁLIDO? public function

    getUser($credentials, UserProviderInterface $userProvider) { $token = new CsrfToken('authenticate', $credentials['csrf_token']); if (!$this->csrfTokenManager->isTokenValid($token)) { throw new InvalidCsrfTokenException(); } return $this->userRepository->findOneBy(['email' => $credentials['email']]); }
  46. LOGIN FORM AUTHENTICATOR CSRF O TOKEN É VÁLIDO? public function

    getUser($credentials, UserProviderInterface $userProvider) { $token = new CsrfToken('authenticate', $credentials['csrf_token']); if (!$this->csrfTokenManager->isTokenValid($token)) { throw new InvalidCsrfTokenException(); } return $this->userRepository->findOneBy(['email' => $credentials['email']]); } <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
  47. LOGIN FORM AUTHENTICATOR CSRF O TOKEN É VÁLIDO? public function

    getUser($credentials, UserProviderInterface $userProvider) { $token = new CsrfToken('authenticate', $credentials['csrf_token']); if (!$this->csrfTokenManager->isTokenValid($token)) { throw new InvalidCsrfTokenException(); } return $this->userRepository->findOneBy(['email' => $credentials['email']]); } <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
  48. LOGIN FORM AUTHENTICATOR CSRF O TOKEN É VÁLIDO? public function

    getUser($credentials, UserProviderInterface $userProvider) { $token = new CsrfToken('authenticate', $credentials['csrf_token']); if (!$this->csrfTokenManager->isTokenValid($token)) { throw new InvalidCsrfTokenException(); } return $this->userRepository->findOneBy(['email' => $credentials['email']]); }
  49. API TOKEN AUTHENTICATOR public function getCredentials(Request $request) { $authorizationHeader =

    $request->headers->get('Authorization'); return $authorizationHeader; }
  50. API TOKEN AUTHENTICATOR public function getUser($credentials, UserProviderInterface $userProvider) { $token

    = $this->apiTokenRepo->findOneBy([ 'token' => $credentials ]); if (!$token) { throw new CustomUserMessageAuthenticationException( 'Invalid API Token' ); } if ($token->isExpired()) { throw new CustomUserMessageAuthenticationException( 'Token expired' ); } return $token->getUser(); }
  51. API TOKEN AUTHENTICATOR public function getUser($credentials, UserProviderInterface $userProvider) { $token

    = $this->apiTokenRepo->findOneBy([ 'token' => $credentials ]); if (!$token) { throw new CustomUserMessageAuthenticationException( 'Invalid API Token' ); } if ($token->isExpired()) { throw new CustomUserMessageAuthenticationException( 'Token expired' ); } return $token->getUser(); }
  52. API TOKEN AUTHENTICATOR public function getUser($credentials, UserProviderInterface $userProvider) { $token

    = $this->apiTokenRepo->findOneBy([ 'token' => $credentials ]); if (!$token) { throw new CustomUserMessageAuthenticationException( 'Invalid API Token' ); } if ($token->isExpired()) { throw new CustomUserMessageAuthenticationException( 'Token expired' ); } return $token->getUser(); }
  53. API TOKEN AUTHENTICATOR public function getUser($credentials, UserProviderInterface $userProvider) { $token

    = $this->apiTokenRepo->findOneBy([ 'token' => $credentials ]); if (!$token) { throw new CustomUserMessageAuthenticationException( 'Invalid API Token' ); } if ($token->isExpired()) { throw new CustomUserMessageAuthenticationException( 'Token expired' ); } return $token->getUser(); }
  54. API TOKEN AUTHENTICATOR public function getUser($credentials, UserProviderInterface $userProvider) { $token

    = $this->apiTokenRepo->findOneBy([ 'token' => $credentials ]); if (!$token) { throw new CustomUserMessageAuthenticationException( 'Invalid API Token' ); } if ($token->isExpired()) { throw new CustomUserMessageAuthenticationException( 'Token expired' ); } return $token->getUser(); }
  55. API TOKEN AUTHENTICATOR public function checkCredentials($credentials, UserInterface $user) { //

    seu código aqui } public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { return new JsonResponse([ 'message' => $exception->getMessageKey() ], 401); } public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) { // seu código aqui }
  56. API TOKEN AUTHENTICATOR public function checkCredentials($credentials, UserInterface $user) { //

    seu código aqui } public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { return new JsonResponse([ 'message' => $exception->getMessageKey() ], 401); } public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) { // seu código aqui }
  57. API TOKEN AUTHENTICATOR public function checkCredentials($credentials, UserInterface $user) { //

    seu código aqui } public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { return new JsonResponse([ 'message' => $exception->getMessageKey() ], 401); } public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) { // seu código aqui }
  58. API TOKEN AUTHENTICATOR public function checkCredentials($credentials, UserInterface $user) { //

    seu código aqui } public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { return new JsonResponse([ 'message' => $exception->getMessageKey() ], 401); } public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) { // seu código aqui }
  59. security: encoders: App\Entity\User: algorithm: argon2i #bcrypt providers: app_user_provider: entity: class:

    App\Entity\User property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: true guard: authenticators: - App\Security\LoginFormAuthenticator - App\Security\ApiTokenAuthenticator entry_point: App\Security\LoginFormAuthenticator SECURITY.YAML
  60. security: encoders: App\Entity\User: algorithm: argon2i #bcrypt providers: app_user_provider: entity: class:

    App\Entity\User property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: true guard: authenticators: - App\Security\LoginFormAuthenticator - App\Security\ApiTokenAuthenticator entry_point: App\Security\LoginFormAuthenticator SECURITY.YAML
  61. security: encoders: App\Entity\User: algorithm: argon2i #bcrypt providers: app_user_provider: entity: class:

    App\Entity\User property: email firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: true guard: authenticators: - App\Security\LoginFormAuthenticator - App\Security\ApiTokenAuthenticator entry_point: App\Security\LoginFormAuthenticator SECURITY.YAML