JWTAuthenticator   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 53
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 16
c 0
b 0
f 0
dl 0
loc 53
rs 10
wmc 9

6 Methods

Rating   Name   Duplication   Size   Complexity  
A authenticate() 0 25 4
A onAuthenticationFailure() 0 3 1
A __construct() 0 4 1
A onAuthenticationSuccess() 0 3 1
A supports() 0 3 1
A start() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AtlassianConnectBundle\Security;
6
7
use AtlassianConnectBundle\Entity\TenantInterface;
8
use Symfony\Component\HttpFoundation\Request;
9
use Symfony\Component\HttpFoundation\Response;
10
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
11
use Symfony\Component\Security\Core\Exception\AuthenticationException;
12
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
13
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
14
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
15
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
16
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
17
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
18
19
class JWTAuthenticator extends AbstractAuthenticator implements AuthenticationEntryPointInterface
20
{
21
    public function __construct(
22
        private JWTUserProviderInterface $userProvider,
23
        private JWTSecurityHelperInterface $securityHelper
24
    ) {
25
    }
26
27
    public function supports(Request $request): ?bool
28
    {
29
        return $this->securityHelper->supportsRequest($request);
30
    }
31
32
    public function authenticate(Request $request): Passport
33
    {
34
        $jwt = $this->securityHelper->getJWTToken($request);
35
36
        if (!$jwt) {
37
            throw new CustomUserMessageAuthenticationException('JWT Token not provided');
38
        }
39
40
        $token = $this->userProvider->getDecodedToken($jwt);
41
        $clientKey = $token->iss;
42
43
        if (!$clientKey) {
44
            throw new CustomUserMessageAuthenticationException(sprintf('API Key %s does not exist', $jwt));
45
        }
46
47
        /** @var TenantInterface $user */
48
        $user = $this->userProvider->loadUserByIdentifier($clientKey);
49
50
        if (property_exists($token, 'sub')) {
51
            // If a user context is present, also set the subject of this user
52
            // See https://developer.atlassian.com/cloud/jira/platform/understanding-jwt-for-connect-apps/#claims
53
            $user->setUsername($token->sub);
54
        }
55
56
        return new SelfValidatingPassport(new UserBadge($clientKey));
57
    }
58
59
    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
60
    {
61
        return null;
62
    }
63
64
    public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
65
    {
66
        return new Response('Authentication Failed: '.$exception->getMessage(), 403);
67
    }
68
69
    public function start(Request $request, AuthenticationException $authException = null): Response
70
    {
71
        return new Response('Authentication header required', 401);
72
    }
73
}
74