From 3164804ac399767b7cd4f6b4b4ac4dbab53c7b2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D1=80=D0=B8=D0=B2=D0=B8=D1=87=20=D0=A1=D0=B5=D1=80?= =?UTF-8?q?=D0=B3=D0=B5=D0=B9?= Date: Tue, 19 Jul 2022 16:27:00 +0300 Subject: [PATCH] Update aunthenticators --- Resources/doc/Security.md | 91 ++++++++++++------------ Security/AbstractClientAuthenticator.php | 46 ++---------- Security/CallbackClientAuthenticator.php | 21 ++++-- Security/FrontApiClientAuthenticator.php | 32 +++++---- 4 files changed, 86 insertions(+), 104 deletions(-) diff --git a/Resources/doc/Security.md b/Resources/doc/Security.md index 9de58c1..d42c32f 100644 --- a/Resources/doc/Security.md +++ b/Resources/doc/Security.md @@ -4,67 +4,70 @@ Example security configuration: ```yaml security: + hide_user_not_found: false providers: - client: - entity: - class: 'App\Entity\Connection' # must implements UserInterface - property: 'clientId' + connection: + entity: { class: App\Entity\Connection, property: clientId } firewalls: - api: - pattern: ^/api - provider: client - anonymous: ~ - lazy: true - stateless: false - guard: - authenticators: - - RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + simple-connection: + pattern: ^/simple-connection + stateless: true + security: false callback: pattern: ^/callback - provider: client - anonymous: ~ - lazy: true + provider: connection stateless: true - guard: - authenticators: - - RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator + custom_authenticators: + - RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator + front: + pattern: ^/(front|login) + provider: connection + stateless: false + remember_me: + secret: '%kernel.secret%' + lifetime: 604800 # 1 week in seconds + always_remember_me: true + custom_authenticators: + - RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator main: - anonymous: true + pattern: ^/ lazy: true access_control: - - { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } # login for programmatically authentication user - - { path: ^/api, roles: ROLE_USER } - - { path: ^/callback, roles: ROLE_USER } + - { path: ^/front, roles: IS_AUTHENTICATED_REMEMBERED } + - { path: ^/simple-connection, roles: PUBLIC_ACCESS } ``` To authenticate the user after creating it, you can use the following code ```php -use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; -use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; + use App\Entity\Connection; + use App\Services\ConnectionManager; + use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface; + use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator; -class AppController extends AbstractController -{ - public function someAction( - Request $request, - GuardAuthenticatorHandler $guardAuthenticatorHandler, - FrontApiClientAuthenticator $frontApiClientAuthenticator, - ConnectionManager $manager - ): Response { - $user = $manager->getUser(); // getting user + class AppController extends AbstractController + { + public function someAction( + Request $request, + Connection $connection, + ConnectionManager $manager, + UserAuthenticatorInterface $userAuthenticator, + FrontApiClientAuthenticator $authenticator + ): Response { + $exist = $manager->search($connection); //get connection - $guardAuthenticatorHandler->authenticateUserAndHandleSuccess( - $user, - $request, - $frontApiClientAuthenticator, - 'api' - ); - // ... + $userAuthenticator->authenticateUser( + $connection, + $authenticator, + $request + ); + } } -} ``` diff --git a/Security/AbstractClientAuthenticator.php b/Security/AbstractClientAuthenticator.php index 227b19e..386ac03 100644 --- a/Security/AbstractClientAuthenticator.php +++ b/Security/AbstractClientAuthenticator.php @@ -8,26 +8,15 @@ 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\Core\User\UserInterface; -use Symfony\Component\Security\Core\User\UserProviderInterface; -use Symfony\Component\Security\Guard\AbstractGuardAuthenticator; +use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -/** - * Class AbstractClientAuthenticator - * - * @package RetailCrm\ServiceBundle\Security - */ -abstract class AbstractClientAuthenticator extends AbstractGuardAuthenticator +abstract class AbstractClientAuthenticator extends AbstractAuthenticator { public const AUTH_FIELD = 'clientId'; private $errorResponseFactory; - /** - * AbstractClientAuthenticator constructor. - * - * @param ErrorJsonResponseFactory $errorResponseFactory - */ public function __construct(ErrorJsonResponseFactory $errorResponseFactory) { $this->errorResponseFactory = $errorResponseFactory; @@ -36,37 +25,12 @@ abstract class AbstractClientAuthenticator extends AbstractGuardAuthenticator /** * {@inheritdoc } */ - public function start(Request $request, AuthenticationException $authException = null): Response - { - $error = new Error(); - $error->message = 'Authentication required'; - - return $this->errorResponseFactory->create($error,Response::HTTP_UNAUTHORIZED); - } + abstract public function supports(Request $request): ?bool; /** * {@inheritdoc } */ - public function getCredentials(Request $request): string - { - return $request->get(static::AUTH_FIELD); - } - - /** - * {@inheritdoc } - */ - public function getUser($credentials, UserProviderInterface $userProvider): ?UserInterface - { - return $userProvider->loadUserByUsername($credentials); - } - - /** - * {@inheritdoc } - */ - public function checkCredentials($credentials, UserInterface $user): bool - { - return true; - } + abstract public function authenticate(Request $request): Passport; /** * {@inheritdoc } diff --git a/Security/CallbackClientAuthenticator.php b/Security/CallbackClientAuthenticator.php index 698e924..1fc51bb 100644 --- a/Security/CallbackClientAuthenticator.php +++ b/Security/CallbackClientAuthenticator.php @@ -3,12 +3,8 @@ namespace RetailCrm\ServiceBundle\Security; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; -/** - * Class CallbackClientAuthenticator - * - * @package RetailCrm\ServiceBundle\Security - */ class CallbackClientAuthenticator extends AbstractClientAuthenticator { /** @@ -26,4 +22,19 @@ class CallbackClientAuthenticator extends AbstractClientAuthenticator { return false; } + + /** + * {@inheritdoc } + */ + public function authenticate(Request $request): Passport + { + $identifier = $request->request->get(static::AUTH_FIELD); + + return new SelfValidatingPassport( + new UserBadge($identifier, function ($userIdentifier) { + return $this->repository->findByIdentifier($userIdentifier); + }), + [] + ); + } } diff --git a/Security/FrontApiClientAuthenticator.php b/Security/FrontApiClientAuthenticator.php index af4fe26..c707f1a 100644 --- a/Security/FrontApiClientAuthenticator.php +++ b/Security/FrontApiClientAuthenticator.php @@ -2,32 +2,29 @@ namespace RetailCrm\ServiceBundle\Security; +use App\Repository\ConnectionRepository; use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\Security; +use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge; +use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; +use Symfony\Component\Security\Http\Authenticator\Passport\Passport; +use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; -/** - * Class FrontApiClientAuthenticator - * - * @package RetailCrm\ServiceBundle\Security - */ class FrontApiClientAuthenticator extends AbstractClientAuthenticator { private $security; + private $repository; - /** - * FrontApiClientAuthenticator constructor. - * - * @param ErrorJsonResponseFactory $errorResponseFactory - * @param Security $security - */ public function __construct( ErrorJsonResponseFactory $errorResponseFactory, - Security $security + Security $security, + ConnectionRepository $repository ) { parent::__construct($errorResponseFactory); $this->security = $security; + $this->repository = $repository; } /** @@ -45,8 +42,15 @@ class FrontApiClientAuthenticator extends AbstractClientAuthenticator /** * {@inheritdoc } */ - public function supportsRememberMe(): bool + public function authenticate(Request $request): Passport { - return true; + $identifier = $request->request->get(static::AUTH_FIELD); + + return new SelfValidatingPassport( + new UserBadge($identifier, function ($userIdentifier) { + return $this->repository->findByIdentifier($userIdentifier); + }), + [new RememberMeBadge()] + ); } }