1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Facile\JoseVerifier; |
6
|
|
|
|
7
|
|
|
use Facile\JoseVerifier\ClaimChecker\AtHashChecker; |
8
|
|
|
use Facile\JoseVerifier\ClaimChecker\CHashChecker; |
9
|
|
|
use Facile\JoseVerifier\ClaimChecker\SHashChecker; |
10
|
|
|
use Jose\Easy\Validate; |
11
|
|
|
use Throwable; |
12
|
|
|
|
13
|
|
|
final class IdTokenVerifier extends AbstractTokenVerifier implements IdTokenVerifierInterface |
14
|
|
|
{ |
15
|
|
|
/** @var string|null */ |
16
|
|
|
protected $accessToken; |
17
|
|
|
|
18
|
|
|
/** @var string|null */ |
19
|
|
|
protected $code; |
20
|
|
|
|
21
|
|
|
/** @var string|null */ |
22
|
|
|
protected $state; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @param string|null $accessToken |
26
|
|
|
* |
27
|
|
|
* @return $this |
28
|
|
|
*/ |
29
|
2 |
|
public function withAccessToken(?string $accessToken): self |
30
|
|
|
{ |
31
|
2 |
|
$new = clone $this; |
32
|
2 |
|
$new->accessToken = $accessToken; |
33
|
|
|
|
34
|
2 |
|
return $new; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @param string|null $code |
39
|
|
|
* |
40
|
|
|
* @return $this |
41
|
|
|
*/ |
42
|
2 |
|
public function withCode(?string $code): self |
43
|
|
|
{ |
44
|
2 |
|
$new = clone $this; |
45
|
2 |
|
$new->code = $code; |
46
|
|
|
|
47
|
2 |
|
return $new; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @param string|null $state |
52
|
|
|
* |
53
|
|
|
* @return $this |
54
|
|
|
*/ |
55
|
2 |
|
public function withState(?string $state): self |
56
|
|
|
{ |
57
|
2 |
|
$new = clone $this; |
58
|
2 |
|
$new->state = $state; |
59
|
|
|
|
60
|
2 |
|
return $new; |
61
|
|
|
} |
62
|
|
|
|
63
|
28 |
|
public function verify(string $jwt): array |
64
|
|
|
{ |
65
|
28 |
|
$jwt = $this->decrypt($jwt); |
66
|
28 |
|
$validator = $this->create($jwt); |
67
|
|
|
|
68
|
25 |
|
$requiredClaims = ['iss', 'sub', 'aud', 'exp', 'iat']; |
69
|
|
|
|
70
|
25 |
|
if (null !== $this->accessToken) { |
71
|
2 |
|
$requiredClaims[] = 'at_hash'; |
72
|
2 |
|
$validator = $validator->claim('s_hash', new AtHashChecker($this->accessToken, $header['alg'] ?? '')); |
73
|
|
|
} |
74
|
|
|
|
75
|
25 |
|
if (null !== $this->code) { |
76
|
2 |
|
$requiredClaims[] = 'c_hash'; |
77
|
2 |
|
$validator = $validator->claim('s_hash', new CHashChecker($this->code, $header['alg'] ?? '')); |
78
|
|
|
} |
79
|
|
|
|
80
|
25 |
|
if (null !== $this->state) { |
81
|
2 |
|
$validator = $validator->claim('s_hash', new SHashChecker($this->state, $header['alg'] ?? '')); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** @var Validate $validator */ |
85
|
25 |
|
$validator = $validator->mandatory($requiredClaims); |
86
|
|
|
|
87
|
|
|
try { |
88
|
25 |
|
return $validator->run()->claims->all(); |
89
|
17 |
|
} catch (Throwable $e) { |
90
|
17 |
|
throw $this->processException($e); |
91
|
|
|
} |
92
|
|
|
} |
93
|
|
|
} |
94
|
|
|
|