From dcd0d76783e1a7a3253f8932b2abf84102ee8af6 Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Wed, 20 Mar 2024 16:28:59 +0100 Subject: [PATCH 1/2] First steps for running proxies without overruling authentication --- api/src/Entity/Endpoint.php | 43 +++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/api/src/Entity/Endpoint.php b/api/src/Entity/Endpoint.php index cf8ee5e4b..50ad0e9c8 100644 --- a/api/src/Entity/Endpoint.php +++ b/api/src/Entity/Endpoint.php @@ -136,17 +136,14 @@ class Endpoint */ private ?string $tag = null; - // @TODO remove totally? - // /** - // * @var string The type of this Endpoint. - // * - // * @Assert\NotNull - // * @Assert\Choice({"gateway-endpoint", "entity-route", "entity-endpoint", "documentation-endpoint"}) - // * - // * @Groups({"read", "write"}) - // * @ORM\Column(type="string") - // */ - // private string $type; + /** + * @var bool Whether or not the proxy should overrule the authentication from the request. + * + * + * @Groups({"read", "write"}) + * @ORM\Column(type="bool", default=false) + */ + private bool $proxyOverrulesAuthentication = false; /** * @var array|null The path of this Endpoint. @@ -615,18 +612,6 @@ public function setTag(?string $tag): self return $this; } - // public function getType(): ?string - // { - // return $this->type; - // } - - // public function setType(string $type): self - // { - // $this->type = $type; - - // return $this; - // } - public function getPath(): ?array { return $this->path; @@ -996,4 +981,16 @@ public function removeFederationProxy(Gateway $federationProxy): self return $this; } + + public function getProxyOverrulesAuthentication(): bool + { + return $this->proxyOverrulesAuthentication; + } + + public function setProxyOverrulesAuthentication(bool $proxyOverrulesAuthentication): self + { + $this->proxyOverrulesAuthentication = $proxyOverrulesAuthentication; + + return $this; + } } From 443f6823f5a30884a168da1bc191bbacbefed65a Mon Sep 17 00:00:00 2001 From: Robert Zondervan Date: Thu, 21 Mar 2024 16:38:40 +0100 Subject: [PATCH 2/2] Database updates, change for authenticators to not run on specific endpoints --- api/migrations/Version20240321082004.php | 31 ++++++++++++++++++++++++ api/src/Entity/Endpoint.php | 7 +++--- api/src/Security/ApiKeyAuthenticator.php | 16 ++++++++++-- api/src/Security/TokenAuthenticator.php | 15 ++++++++++-- 4 files changed, 61 insertions(+), 8 deletions(-) create mode 100644 api/migrations/Version20240321082004.php diff --git a/api/migrations/Version20240321082004.php b/api/migrations/Version20240321082004.php new file mode 100644 index 000000000..08de35d0f --- /dev/null +++ b/api/migrations/Version20240321082004.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE endpoint ADD proxy_overrules_authentication BOOLEAN DEFAULT false'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE endpoint DROP proxy_overrules_authentication'); + } +} diff --git a/api/src/Entity/Endpoint.php b/api/src/Entity/Endpoint.php index 50ad0e9c8..d519f46ea 100644 --- a/api/src/Entity/Endpoint.php +++ b/api/src/Entity/Endpoint.php @@ -139,11 +139,10 @@ class Endpoint /** * @var bool Whether or not the proxy should overrule the authentication from the request. * - * * @Groups({"read", "write"}) - * @ORM\Column(type="bool", default=false) + * @ORM\Column(type="boolean", options={"default":false}, nullable=true) */ - private bool $proxyOverrulesAuthentication = false; + private ?bool $proxyOverrulesAuthentication = false; /** * @var array|null The path of this Endpoint. @@ -982,7 +981,7 @@ public function removeFederationProxy(Gateway $federationProxy): self return $this; } - public function getProxyOverrulesAuthentication(): bool + public function getProxyOverrulesAuthentication(): ?bool { return $this->proxyOverrulesAuthentication; } diff --git a/api/src/Security/ApiKeyAuthenticator.php b/api/src/Security/ApiKeyAuthenticator.php index a5c04a7f0..c881eb074 100644 --- a/api/src/Security/ApiKeyAuthenticator.php +++ b/api/src/Security/ApiKeyAuthenticator.php @@ -3,6 +3,7 @@ namespace App\Security; use App\Entity\Application; +use App\Entity\Endpoint; use App\Entity\User; use App\Security\User\AuthenticationUser; use Doctrine\ORM\EntityManagerInterface; @@ -37,8 +38,18 @@ public function __construct( */ public function supports(Request $request): ?bool { - return $request->headers->has('Authorization') && - strpos($request->headers->get('Authorization'), 'Bearer') === false; + if($request->headers->has('Authorization') === true && + strpos($request->headers->get('Authorization'), 'Bearer') === false) { + + $pathTemp = explode('/api/', $request->getPathInfo(), 2); + $endpoint = null; + if(count($pathTemp) > 1) { + $path = $pathTemp[1]; + $endpoint = $this->entityManager->getRepository(Endpoint::class)->findByMethodRegex($request->getMethod(), $path); + } + return ($endpoint instanceof Endpoint === false || $endpoint->getProxyOverrulesAuthentication() == false); + } + return false; } private function prefixRoles(array $roles): array @@ -130,6 +141,7 @@ public function authenticate(Request $request): PassportInterface 'roles' => $roleArray['roles'], ]; + return new Passport( new UserBadge($userArray['id'], function ($userIdentifier) use ($userArray) { return new AuthenticationUser( diff --git a/api/src/Security/TokenAuthenticator.php b/api/src/Security/TokenAuthenticator.php index f12845b68..e0b886b23 100644 --- a/api/src/Security/TokenAuthenticator.php +++ b/api/src/Security/TokenAuthenticator.php @@ -3,6 +3,7 @@ namespace App\Security; use App\Entity\Authentication; +use App\Entity\Endpoint; use App\Entity\SecurityGroup; use App\Exception\GatewayException; use App\Security\User\AuthenticationUser; @@ -52,8 +53,18 @@ public function __construct( */ public function supports(Request $request): ?bool { - return $request->headers->has('Authorization') && - strpos($request->headers->get('Authorization'), 'Bearer') === 0; + if($request->headers->has('Authorization') === true && + strpos($request->headers->get('Authorization'), 'Bearer') === 0) { + + $pathTemp = explode('/api/', $request->getPathInfo(), 2); + $endpoint = null; + if(count($pathTemp) > 1) { + $path = $pathTemp[1]; + $endpoint = $this->entityManager->getRepository(Endpoint::class)->findByMethodRegex($request->getMethod(), $path); + } + return ($endpoint instanceof Endpoint === false || $endpoint->getProxyOverrulesAuthentication() == false); + } + return false; } /**