Fix authenticators and dependecy injection
This commit is contained in:
parent
6243bd1261
commit
180ccab466
@ -66,8 +66,8 @@ class RetailCrmServiceExtension extends Extension
|
|||||||
$container
|
$container
|
||||||
->register(CallbackValueResolver::class)
|
->register(CallbackValueResolver::class)
|
||||||
->setArguments([
|
->setArguments([
|
||||||
new Reference($container->getParameter('retail_crm_service.request_schema.callback.serializer')),
|
|
||||||
new Reference('validator'),
|
new Reference('validator'),
|
||||||
|
new Reference($container->getParameter('retail_crm_service.request_schema.callback.serializer')),
|
||||||
$container->getParameter('retail_crm_service.request_schema.callback.supports')
|
$container->getParameter('retail_crm_service.request_schema.callback.supports')
|
||||||
])
|
])
|
||||||
->addTag('controller.argument_value_resolver', ['priority' => 50])
|
->addTag('controller.argument_value_resolver', ['priority' => 50])
|
||||||
@ -76,8 +76,8 @@ class RetailCrmServiceExtension extends Extension
|
|||||||
$container
|
$container
|
||||||
->register(ClientValueResolver::class)
|
->register(ClientValueResolver::class)
|
||||||
->setArguments([
|
->setArguments([
|
||||||
new Reference($container->getParameter('retail_crm_service.request_schema.client.serializer')),
|
|
||||||
new Reference('validator'),
|
new Reference('validator'),
|
||||||
|
new Reference($container->getParameter('retail_crm_service.request_schema.client.serializer')),
|
||||||
$container->getParameter('retail_crm_service.request_schema.client.supports')
|
$container->getParameter('retail_crm_service.request_schema.client.supports')
|
||||||
])
|
])
|
||||||
->addTag('controller.argument_value_resolver', ['priority' => 50])
|
->addTag('controller.argument_value_resolver', ['priority' => 50])
|
||||||
|
@ -23,12 +23,13 @@ security:
|
|||||||
custom_authenticators:
|
custom_authenticators:
|
||||||
- RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator
|
- RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator
|
||||||
front:
|
front:
|
||||||
pattern: ^/(front|login)
|
pattern: ^/auth
|
||||||
provider: connection
|
provider: connection
|
||||||
stateless: false
|
stateless: false
|
||||||
remember_me:
|
remember_me:
|
||||||
secret: '%kernel.secret%'
|
secret: '%kernel.secret%'
|
||||||
lifetime: 604800 # 1 week in seconds
|
lifetime: 604800 # 1 week in seconds
|
||||||
|
signature_properties: ['clientId']
|
||||||
always_remember_me: true
|
always_remember_me: true
|
||||||
custom_authenticators:
|
custom_authenticators:
|
||||||
- RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator
|
- RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator
|
||||||
@ -41,33 +42,27 @@ security:
|
|||||||
- { path: ^/simple-connection, roles: PUBLIC_ACCESS }
|
- { path: ^/simple-connection, roles: PUBLIC_ACCESS }
|
||||||
```
|
```
|
||||||
|
|
||||||
To authenticate the user after creating it, you can use the following code
|
Login controller will be called after the authenticator successfully authenticates the user. You can get the authenticated user, generate a token (or whatever you need to return) and return response:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
|
||||||
use App\Entity\Connection;
|
use App\Entity\User;
|
||||||
use App\Services\ConnectionManager;
|
use Symfony\Component\Security\Http\Attribute\CurrentUser;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
|
|
||||||
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
|
||||||
|
|
||||||
class AppController extends AbstractController
|
class ApiLoginController extends AbstractController
|
||||||
{
|
{
|
||||||
public function someAction(
|
#[Route('/auth', name: 'auth')]
|
||||||
Request $request,
|
public function auth(#[CurrentUser] ?User $user): Response
|
||||||
Connection $connection,
|
{
|
||||||
ConnectionManager $manager,
|
$token = ...; // somehow create an API token for $user
|
||||||
UserAuthenticatorInterface $userAuthenticator,
|
|
||||||
FrontApiClientAuthenticator $authenticator
|
return $this->json([
|
||||||
): Response {
|
'user' => $user->getUserIdentifier(),
|
||||||
$exist = $manager->search($connection); //get connection
|
'token' => $token,
|
||||||
|
]);
|
||||||
$userAuthenticator->authenticateUser(
|
|
||||||
$connection,
|
|
||||||
$authenticator,
|
|
||||||
$request
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The <code>#[CurrentUser]</code> can only be used in controller arguments to retrieve the authenticated user. In services, you would use getUser().
|
||||||
|
@ -16,8 +16,6 @@ abstract class AbstractClientAuthenticator extends AbstractAuthenticator
|
|||||||
{
|
{
|
||||||
public const AUTH_FIELD = 'clientId';
|
public const AUTH_FIELD = 'clientId';
|
||||||
|
|
||||||
protected ObjectRepository $userRepository;
|
|
||||||
|
|
||||||
public function __construct(private ErrorJsonResponseFactory $errorResponseFactory)
|
public function __construct(private ErrorJsonResponseFactory $errorResponseFactory)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -38,9 +36,4 @@ abstract class AbstractClientAuthenticator extends AbstractAuthenticator
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUserRepository(ObjectRepository $userRepository): void
|
|
||||||
{
|
|
||||||
$this->userRepository = $userRepository;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,8 +24,7 @@ class CallbackClientAuthenticator extends AbstractClientAuthenticator
|
|||||||
|
|
||||||
return new SelfValidatingPassport(
|
return new SelfValidatingPassport(
|
||||||
new UserBadge(
|
new UserBadge(
|
||||||
$identifier,
|
$identifier
|
||||||
fn ($userIdentifier) => $this->userRepository->findOneBy([static::AUTH_FIELD => $userIdentifier])
|
|
||||||
),
|
),
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
@ -38,8 +38,7 @@ class FrontApiClientAuthenticator extends AbstractClientAuthenticator
|
|||||||
|
|
||||||
return new SelfValidatingPassport(
|
return new SelfValidatingPassport(
|
||||||
new UserBadge(
|
new UserBadge(
|
||||||
$identifier,
|
$identifier
|
||||||
fn ($userIdentifier) => $this->userRepository->findOneBy([static::AUTH_FIELD => $userIdentifier]),
|
|
||||||
),
|
),
|
||||||
[new RememberMeBadge()]
|
[new RememberMeBadge()]
|
||||||
);
|
);
|
||||||
|
@ -6,6 +6,8 @@ use Symfony\Component\Security\Core\User\UserInterface;
|
|||||||
|
|
||||||
class User implements UserInterface
|
class User implements UserInterface
|
||||||
{
|
{
|
||||||
|
protected string $clientId = '123';
|
||||||
|
|
||||||
public function getRoles(): array
|
public function getRoles(): array
|
||||||
{
|
{
|
||||||
return ["USER"];
|
return ["USER"];
|
||||||
@ -22,6 +24,6 @@ class User implements UserInterface
|
|||||||
|
|
||||||
public function getUserIdentifier(): string
|
public function getUserIdentifier(): string
|
||||||
{
|
{
|
||||||
return 'identifier';
|
return $this->clientId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||||
|
|
||||||
class CallbackClientAuthenticatorTest extends TestCase
|
class CallbackClientAuthenticatorTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -58,19 +59,13 @@ class CallbackClientAuthenticatorTest extends TestCase
|
|||||||
$errorResponseFactory = $this->createMock(ErrorJsonResponseFactory::class);
|
$errorResponseFactory = $this->createMock(ErrorJsonResponseFactory::class);
|
||||||
$user = new User();
|
$user = new User();
|
||||||
|
|
||||||
$userRepository = $this->createMock(ObjectRepository::class);
|
|
||||||
$userRepository
|
|
||||||
->expects(static::once())
|
|
||||||
->method('findOneBy')
|
|
||||||
->willReturn($user)
|
|
||||||
;
|
|
||||||
|
|
||||||
$auth = new CallbackClientAuthenticator($errorResponseFactory);
|
$auth = new CallbackClientAuthenticator($errorResponseFactory);
|
||||||
$auth->setUserRepository($userRepository);
|
|
||||||
|
|
||||||
$passport = $auth->authenticate(new Request([], [CallbackClientAuthenticator::AUTH_FIELD => '123']));
|
$passport = $auth->authenticate(new Request([], [CallbackClientAuthenticator::AUTH_FIELD => '123']));
|
||||||
$authUser = $passport->getUser();
|
static::assertTrue($passport->hasBadge(UserBadge::class));
|
||||||
static::assertEquals($user, $authUser);
|
static::assertEquals(
|
||||||
|
$user->getUserIdentifier(),
|
||||||
|
$passport->getBadge(UserBadge::class)->getUserIdentifier()
|
||||||
|
);
|
||||||
|
|
||||||
$this->expectException(AuthenticationException::class);
|
$this->expectException(AuthenticationException::class);
|
||||||
$auth->authenticate(new Request());
|
$auth->authenticate(new Request());
|
||||||
|
@ -13,6 +13,7 @@ use Symfony\Component\HttpFoundation\Response;
|
|||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||||
|
|
||||||
class FrontApiClientAuthenticatorTest extends TestCase
|
class FrontApiClientAuthenticatorTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -65,19 +66,14 @@ class FrontApiClientAuthenticatorTest extends TestCase
|
|||||||
$security = $this->createMock(Security::class);
|
$security = $this->createMock(Security::class);
|
||||||
|
|
||||||
$user = new User();
|
$user = new User();
|
||||||
$userRepository = $this->createMock(ObjectRepository::class);
|
|
||||||
$userRepository
|
|
||||||
->expects(static::once())
|
|
||||||
->method('findOneBy')
|
|
||||||
->with([FrontApiClientAuthenticator::AUTH_FIELD => '123'])
|
|
||||||
->willReturn($user)
|
|
||||||
;
|
|
||||||
$auth = new FrontApiClientAuthenticator($errorResponseFactory, $security);
|
$auth = new FrontApiClientAuthenticator($errorResponseFactory, $security);
|
||||||
$auth->setUserRepository($userRepository);
|
|
||||||
|
|
||||||
$passport = $auth->authenticate(new Request([], [FrontApiClientAuthenticator::AUTH_FIELD => '123']));
|
$passport = $auth->authenticate(new Request([], [FrontApiClientAuthenticator::AUTH_FIELD => '123']));
|
||||||
$authUser = $passport->getUser();
|
static::assertTrue($passport->hasBadge(UserBadge::class));
|
||||||
static::assertEquals($user, $authUser);
|
static::assertEquals(
|
||||||
|
$user->getUserIdentifier(),
|
||||||
|
$passport->getBadge(UserBadge::class)->getUserIdentifier()
|
||||||
|
);
|
||||||
|
|
||||||
$this->expectException(AuthenticationException::class);
|
$this->expectException(AuthenticationException::class);
|
||||||
$auth->authenticate(new Request());
|
$auth->authenticate(new Request());
|
||||||
|
Loading…
Reference in New Issue
Block a user