feat: integrated OAuth2 server
This commit is contained in:
@@ -1,60 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Security;
|
||||
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
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\Exception\CustomUserMessageAuthenticationException;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
|
||||
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 ApiKeyAuthenticator extends AbstractAuthenticator
|
||||
{
|
||||
public function __construct(private readonly array $apiKeys)
|
||||
{
|
||||
}
|
||||
|
||||
public function supports(Request $request): ?bool
|
||||
{
|
||||
return $request->headers->has('X-BPN-API-KEY');
|
||||
}
|
||||
|
||||
public function authenticate(Request $request): Passport
|
||||
{
|
||||
$apiKey = $request->headers->get('X-BPN-API-KEY');
|
||||
|
||||
if (null === $apiKey) {
|
||||
throw new CustomUserMessageAuthenticationException('No API key provided');
|
||||
}
|
||||
|
||||
if (false === in_array($apiKey, $this->apiKeys)) {
|
||||
throw new CustomUserMessageAuthenticationException('Invalid API key');
|
||||
}
|
||||
|
||||
return new SelfValidatingPassport(
|
||||
new UserBadge($apiKey, function (string $userIdentifier) use ($apiKey): ?UserInterface {
|
||||
return new ApiUser($apiKey);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
|
||||
{
|
||||
$data = [
|
||||
'message' => 'Authentication missing or failed',
|
||||
];
|
||||
|
||||
return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Security;
|
||||
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
class ApiUser implements UserInterface
|
||||
{
|
||||
public function __construct(private readonly string $apiKey)
|
||||
{
|
||||
}
|
||||
|
||||
public function getRoles(): array
|
||||
{
|
||||
return ['ROLE_USER', 'ROLE_API'];
|
||||
}
|
||||
|
||||
public function eraseCredentials(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function getUserIdentifier(): string
|
||||
{
|
||||
return $this->apiKey;
|
||||
}
|
||||
}
|
||||
@@ -22,9 +22,12 @@ 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;
|
||||
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
|
||||
use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
||||
|
||||
class BpnAuthenticator extends AbstractLoginFormAuthenticator implements AuthenticationEntryPointInterface
|
||||
{
|
||||
use TargetPathTrait;
|
||||
|
||||
public function __construct(
|
||||
private readonly UrlGeneratorInterface $urlGenerator,
|
||||
private readonly ApiClient $apiClient,
|
||||
@@ -60,7 +63,7 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
$csrfToken = $request->request->getString('_csrf_token');
|
||||
|
||||
return new SelfValidatingPassport(
|
||||
new UserBadge($email, function () use ($email, $password, $response, $request) {
|
||||
new UserBadge($email, function () use ($email, $password, $response) {
|
||||
return $this->createOrUpdateLocalUser($email, $password, $response->personId, $response->addressId);
|
||||
}),
|
||||
[
|
||||
@@ -106,6 +109,10 @@ class BpnAuthenticator extends AbstractLoginFormAuthenticator implements Authent
|
||||
'email' => $token->getUserIdentifier(),
|
||||
]);
|
||||
|
||||
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
|
||||
return new RedirectResponse($targetPath);
|
||||
}
|
||||
|
||||
return new RedirectResponse($this->urlGenerator->generate('app_personal_data'));
|
||||
}
|
||||
|
||||
|
||||
@@ -13,28 +13,28 @@ class Crypt
|
||||
|
||||
public function encrypt(string $message): string
|
||||
{
|
||||
$privateKey = PrivateKey::fromFile($this->path . '/private.key');
|
||||
$privateKey = PrivateKey::fromFile($this->path.'/private.key');
|
||||
|
||||
return $privateKey->encrypt($message);
|
||||
}
|
||||
|
||||
public function decrypt(string $message): string
|
||||
{
|
||||
$publicKey = PublicKey::fromFile($this->path . '/public.key');
|
||||
$publicKey = PublicKey::fromFile($this->path.'/public.key');
|
||||
|
||||
return $publicKey->decrypt($message);
|
||||
}
|
||||
|
||||
public function sign(string $message): string
|
||||
{
|
||||
$privateKey = PrivateKey::fromFile($this->path . '/private.key');
|
||||
$privateKey = PrivateKey::fromFile($this->path.'/private.key');
|
||||
|
||||
return $privateKey->sign($message);
|
||||
}
|
||||
|
||||
public function verify(string $message, string $signature): bool
|
||||
{
|
||||
$publicKey = PublicKey::fromFile($this->path . '/public.key');
|
||||
$publicKey = PublicKey::fromFile($this->path.'/public.key');
|
||||
|
||||
return $publicKey->verify($message, $signature);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user