Completed
Push — master ( f0a385...b2cd20 )
by Thomas Mauro
01:33
created

JWTVerifierTest::testShouldValidateToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 27
rs 9.488
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Facile\JoseVerifierTest;
6
7
use Base64Url\Base64Url;
8
use Facile\JoseVerifier\AbstractTokenVerifier;
9
use Facile\JoseVerifier\Decrypter\TokenDecrypterInterface;
10
use Facile\JoseVerifier\Exception\InvalidTokenException;
11
use function Facile\JoseVerifier\jose_secret_key;
12
use Facile\JoseVerifier\JWK\MemoryJwksProvider;
13
use Facile\JoseVerifier\JWTVerifier;
14
use Jose\Component\KeyManagement\JWKFactory;
15
use function time;
16
17
class JWTVerifierTest extends AbstractTokenVerifierTestCase
18
{
19
    /**
20
     * @param TokenDecrypterInterface|null $decrypter
21
     *
22
     * @return JWTVerifier
23
     */
24
    protected function buildVerifier(TokenDecrypterInterface $decrypter = null): AbstractTokenVerifier
25
    {
26
        return new JWTVerifier('https://issuer.com', 'client-id', $decrypter);
27
    }
28
29
    public function testShouldValidateToken(): void
30
    {
31
        $jwk = JWKFactory::createRSAKey(2048, ['alg' => 'RS256', 'use' => 'sig']);
32
        $payload = [
33
            'iss' => 'https://issuer.com',
34
            'sub' => 'client-id',
35
            'aud' => 'client-id',
36
            'azp' => 'client-id',
37
            'exp' => time() + 600,
38
            'iat' => time(),
39
            'auth_time' => time() - 100,
40
        ];
41
        $token = $this->createSignedToken($payload, [
42
            'alg' => 'RS256',
43
        ], $jwk);
44
45
        $jwks = ['keys' => [$jwk->toPublic()->all()]];
46
47
        $result = $this->buildVerifier()
48
            ->withJwksProvider(new MemoryJwksProvider($jwks))
49
            ->withAuthTimeRequired(true)
50
            ->withNonce('nonce')
51
            ->withExpectedAlg('RS256')
52
            ->verify($token);
53
54
        self::assertSame($payload, $result);
0 ignored issues
show
Bug introduced by
The method assertSame() does not seem to exist on object<Facile\JoseVerifierTest\JWTVerifierTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
55
    }
56
57
    public function testShouldFailWithoutKey(): void
58
    {
59
        $this->expectException(InvalidTokenException::class);
0 ignored issues
show
Bug introduced by
The method expectException() does not seem to exist on object<Facile\JoseVerifierTest\JWTVerifierTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
60
61
        $jwk = JWKFactory::createRSAKey(2048, ['alg' => 'RS256', 'use' => 'sig']);
62
        $payload = [
63
            'iss' => 'https://issuer.com',
64
            'sub' => 'client-id',
65
            'aud' => 'client-id',
66
            'azp' => 'client-id',
67
            'exp' => time() + 600,
68
            'iat' => time(),
69
            'auth_time' => time() - 100,
70
        ];
71
        $token = $this->createSignedToken($payload, [
72
            'alg' => 'RS256',
73
        ], $jwk);
74
75
        $jwk2 = JWKFactory::createRSAKey(2048, ['alg' => 'RS256', 'use' => 'sig']);
76
        $jwks = ['keys' => [$jwk2->toPublic()->all()]];
77
78
        $this->buildVerifier()
79
            ->withJwksProvider(new MemoryJwksProvider($jwks))
80
            ->withExpectedAlg('RS256')
81
            ->verify($token);
82
    }
83
84
    public function verifyTokenProvider(): array
85
    {
86
        return [
87
            [
88
                [
89
                    'iss' => 'https://issuer.com',
90
                    'sub' => 'client-id',
91
                    'aud' => 'client-id',
92
                    'azp' => 'client-id',
93
                    'exp' => time() + 600,
94
                    'iat' => time(),
95
                    'auth_time' => time() - 100,
96
                ],
97
                true,
98
            ],
99
            // wrong issuer
100
            [
101
                [
102
                    'iss' => 'https://issuer.com-wrong',
103
                    'sub' => 'client-id',
104
                    'aud' => 'client-id',
105
                    'exp' => time() + 600,
106
                    'iat' => time(),
107
                    'auth_time' => time() - 100,
108
                ],
109
                false,
110
            ],
111
            // wrong aud
112
            [
113
                [
114
                    'iss' => 'https://issuer.com',
115
                    'sub' => 'client-id',
116
                    'aud' => 'wrong-client-id',
117
                    'exp' => time() + 600,
118
                    'iat' => time(),
119
                    'auth_time' => time() - 100,
120
                ],
121
                false,
122
            ],
123
            // wrong exp
124
            [
125
                [
126
                    'iss' => 'https://issuer.com',
127
                    'sub' => 'client-id',
128
                    'aud' => 'client-id',
129
                    'exp' => time() - 1,
130
                    'iat' => time(),
131
                    'auth_time' => time() - 100,
132
                ],
133
                false,
134
            ],
135
            // wrong auth_time
136
            [
137
                [
138
                    'iss' => 'https://issuer.com',
139
                    'sub' => 'client-id',
140
                    'aud' => 'client-id',
141
                    'exp' => time() - 1,
142
                    'iat' => time(),
143
                    'auth_time' => time() - 400,
144
                ],
145
                false,
146
            ],
147
            // wrong azp
148
            [
149
                [
150
                    'iss' => 'https://issuer.com',
151
                    'sub' => 'client-id',
152
                    'aud' => 'client-id',
153
                    'exp' => time() - 1,
154
                    'iat' => time(),
155
                    'azp' => 'foo',
156
                    'auth_time' => time() - 400,
157
                ],
158
                false,
159
            ],
160
            // missing sub
161
            [
162
                [
163
                    'iss' => 'https://issuer.com',
164
                    'aud' => 'client-id',
165
                    'exp' => time() + 600,
166
                    'iat' => time(),
167
                    'auth_time' => time() - 100,
168
                ],
169
                false,
170
            ],
171
            // missing iss
172
            [
173
                [
174
                    'sub' => 'client-id',
175
                    'aud' => 'client-id',
176
                    'exp' => time() + 300,
177
                    'iat' => time(),
178
                    'auth_time' => time() - 100,
179
                ],
180
                false,
181
            ],
182
            // missing aud
183
            [
184
                [
185
                    'iss' => 'https://issuer.com',
186
                    'sub' => 'client-id',
187
                    'exp' => time() + 300,
188
                    'iat' => time(),
189
                    'auth_time' => time() - 100,
190
                ],
191
                false,
192
            ],
193
            // missing exp
194
            [
195
                [
196
                    'iss' => 'https://issuer.com',
197
                    'sub' => 'client-id',
198
                    'aud' => 'client-id',
199
                    'iat' => time(),
200
                    'auth_time' => time() - 100,
201
                ],
202
                false,
203
            ],
204
            // missing iat
205
            [
206
                [
207
                    'iss' => 'https://issuer.com',
208
                    'sub' => 'client-id',
209
                    'aud' => 'client-id',
210
                    'exp' => time() + 300,
211
                    'auth_time' => time() - 100,
212
                ],
213
                false,
214
            ],
215
        ];
216
    }
217
218
    /**
219
     * @dataProvider verifyTokenProvider
220
     *
221
     * @param array $payload
222
     * @param bool $expected
223
     *
224
     * @throws \Exception
225
     */
226
    public function testValidateTokenWithAsyKey(array $payload, bool $expected): void
227
    {
228
        if (! $expected) {
229
            $this->expectException(InvalidTokenException::class);
0 ignored issues
show
Bug introduced by
The method expectException() does not seem to exist on object<Facile\JoseVerifierTest\JWTVerifierTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
230
        }
231
232
        $clientSecret = Base64Url::encode(\random_bytes(32));
233
        $jwk = jose_secret_key($clientSecret);
234
235
        $token = $this->createSignedToken($payload, [
236
            'alg' => 'HS256',
237
        ], $jwk);
238
239
        $result = $this->buildVerifier()
240
            ->withJwksProvider(new MemoryJwksProvider())
241
            ->withAuthTimeRequired(true)
242
            ->withNonce('nonce')
243
            ->withClientSecret($clientSecret)
244
            ->withExpectedAlg('HS256')
245
            ->verify($token);
246
247
        self::assertSame($payload, $result);
0 ignored issues
show
Bug introduced by
The method assertSame() does not seem to exist on object<Facile\JoseVerifierTest\JWTVerifierTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
248
249
        self::assertSame($payload, $result);
0 ignored issues
show
Bug introduced by
The method assertSame() does not seem to exist on object<Facile\JoseVerifierTest\JWTVerifierTest>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
250
    }
251
}
252