PrivateKeyJwt   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Test Coverage

Coverage 96.67%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 30
dl 0
loc 80
ccs 29
cts 30
cp 0.9667
rs 10
c 1
b 0
f 0
wmc 4

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A getSupportedMethod() 0 3 1
A createAuthJwt() 0 35 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Facile\OpenIDClient\AuthMethod;
6
7
use function array_merge;
8
use Facile\OpenIDClient\AlgorithmManagerBuilder;
9
use function Facile\OpenIDClient\base64url_encode;
10
use Facile\OpenIDClient\Client\ClientInterface as OpenIDClient;
11
use Facile\OpenIDClient\Exception\RuntimeException;
12
use Jose\Component\Core\JWK;
13
use Jose\Component\Core\JWKSet;
14
use Jose\Component\Signature\JWSBuilder;
15
use Jose\Component\Signature\Serializer\CompactSerializer;
16
use Jose\Component\Signature\Serializer\JWSSerializer;
17
use function json_encode;
18
use function random_bytes;
19
use function time;
20
21
final class PrivateKeyJwt extends AbstractJwtAuth
22
{
23
    /** @var JWSBuilder */
24
    private $jwsBuilder;
25
26
    /** @var JWSSerializer */
27
    private $jwsSerializer;
28
29
    /** @var null|JWK */
30
    private $jwk;
31
32
    /** @var int */
33
    private $tokenTTL;
34
35
    /**
36
     * PrivateKeyJwt constructor.
37
     *
38
     * @param null|JWSBuilder $jwsBuilder
39
     * @param null|JWSSerializer $serializer
40
     * @param null|JWK $jwk
41
     * @param int $tokenTTL
42
     */
43 4
    public function __construct(
44
        ?JWSBuilder $jwsBuilder = null,
45
        ?JWSSerializer $serializer = null,
46
        ?JWK $jwk = null,
47
        int $tokenTTL = 60
48
    ) {
49 4
        $this->jwsBuilder = $jwsBuilder ?? new JWSBuilder((new AlgorithmManagerBuilder())->build());
50 4
        $this->jwsSerializer = $serializer ?? new CompactSerializer();
51 4
        $this->jwk = $jwk;
52 4
        $this->tokenTTL = $tokenTTL;
53 4
    }
54
55 2
    public function getSupportedMethod(): string
56
    {
57 2
        return 'private_key_jwt';
58
    }
59
60
    /**
61
     * @param OpenIDClient $client
62
     * @param array<string, mixed> $claims
63
     *
64
     * @return string
65
     */
66 2
    protected function createAuthJwt(OpenIDClient $client, array $claims = []): string
67
    {
68 2
        $issuer = $client->getIssuer();
69 2
        $issuerMetadata = $issuer->getMetadata();
70
71 2
        $clientId = $client->getMetadata()->getClientId();
72
73 2
        $jwk = $this->jwk ?? JWKSet::createFromKeyData($client->getJwksProvider()->getJwks())->selectKey('sig');
74
75 2
        if (null === $jwk) {
76
            throw new RuntimeException('Unable to get a client signature jwk');
77
        }
78
79 2
        $time = time();
80 2
        $jti = base64url_encode(random_bytes(32));
81
82
        /** @var string $payload */
83 2
        $payload = json_encode(array_merge(
84 2
            $claims,
85
            [
86 2
                'iss' => $clientId,
87 2
                'sub' => $clientId,
88 2
                'aud' => $issuerMetadata->getIssuer(),
89 2
                'iat' => $time,
90 2
                'exp' => $time + $this->tokenTTL,
91 2
                'jti' => $jti,
92
            ]
93
        ));
94
95 2
        $jws = $this->jwsBuilder->create()
96 2
            ->withPayload($payload)
97 2
            ->addSignature($jwk, ['alg' => $jwk->get('alg'), 'jti' => $jti])
98 2
            ->build();
99
100 2
        return $this->jwsSerializer->serialize($jws, 0);
101
    }
102
}
103