8
8
9
9
namespace Magento \Framework \Jwt ;
10
10
11
+ use Magento \Framework \Jwt \Claim \ExpirationTime ;
12
+ use Magento \Framework \Jwt \Claim \IssuedAt ;
13
+ use Magento \Framework \Jwt \Claim \Issuer ;
14
+ use Magento \Framework \Jwt \Claim \JwtId ;
11
15
use Magento \Framework \Jwt \Claim \PrivateClaim ;
16
+ use Magento \Framework \Jwt \Claim \Subject ;
12
17
use Magento \Framework \Jwt \Header \Critical ;
13
18
use Magento \Framework \Jwt \Header \PrivateHeaderParameter ;
14
19
use Magento \Framework \Jwt \Header \PublicHeaderParameter ;
@@ -58,7 +63,9 @@ public function testCreateRead(
58
63
$ recreated = $ this ->manager ->read ($ token , $ readEncryption );
59
64
60
65
//Verifying header
61
- $ this ->verifyHeader ($ jwt ->getHeader (), $ recreated ->getHeader ());
66
+ if ((!$ jwt instanceof JwsInterface && !$ jwt instanceof JweInterface) || count ($ jwt ->getProtectedHeaders ()) == 1 ) {
67
+ $ this ->verifyAgainstHeaders ([$ jwt ->getHeader ()], $ recreated ->getHeader ());
68
+ }
62
69
//Verifying payload
63
70
$ this ->assertEquals ($ jwt ->getPayload ()->getContent (), $ recreated ->getPayload ()->getContent ());
64
71
if ($ jwt ->getPayload () instanceof ClaimsPayloadInterface) {
@@ -76,9 +83,9 @@ public function testCreateRead(
76
83
$ this ->assertNull ($ recreated ->getUnprotectedHeaders ());
77
84
} else {
78
85
$ this ->assertTrue (count ($ recreated ->getUnprotectedHeaders ()) >= 1 );
79
- $ this ->verifyHeader ($ jwt ->getUnprotectedHeaders ()[ 0 ] , $ recreated ->getUnprotectedHeaders ()[0 ]);
86
+ $ this ->verifyAgainstHeaders ($ jwt ->getUnprotectedHeaders (), $ recreated ->getUnprotectedHeaders ()[0 ]);
80
87
}
81
- $ this ->verifyHeader ($ jwt ->getProtectedHeaders ()[ 0 ] , $ recreated ->getProtectedHeaders ()[0 ]);
88
+ $ this ->verifyAgainstHeaders ($ jwt ->getProtectedHeaders (), $ recreated ->getProtectedHeaders ()[0 ]);
82
89
}
83
90
if ($ jwt instanceof JweInterface) {
84
91
$ this ->assertInstanceOf (JweInterface::class, $ recreated );
@@ -107,13 +114,14 @@ public function getTokenVariants(): array
107
114
[
108
115
new PrivateClaim ('custom-claim ' , 'value ' ),
109
116
new PrivateClaim ('custom-claim2 ' , 'value2 ' ),
110
- new PrivateClaim ('custom-claim3 ' , 'value3 ' )
117
+ new PrivateClaim ('custom-claim3 ' , 'value3 ' ),
118
+ new IssuedAt (new \DateTimeImmutable ()),
119
+ new Issuer ('magento.com ' )
111
120
]
112
121
),
113
122
null
114
123
);
115
-
116
- $ flatJwsWithUnprotectedHeader = new Jws (
124
+ $ jwsWithUnprotectedHeader = new Jws (
117
125
[
118
126
new JwsHeader (
119
127
[
@@ -125,7 +133,8 @@ public function getTokenVariants(): array
125
133
new ClaimsPayload (
126
134
[
127
135
new PrivateClaim ('custom-claim ' , 'value ' ),
128
- new PrivateClaim ('custom-claim2 ' , 'value2 ' )
136
+ new PrivateClaim ('custom-claim2 ' , 'value2 ' ),
137
+ new ExpirationTime (new \DateTimeImmutable ())
129
138
]
130
139
),
131
140
[
@@ -136,15 +145,42 @@ public function getTokenVariants(): array
136
145
)
137
146
]
138
147
);
148
+ $ compactJws = new Jws (
149
+ [
150
+ new JwsHeader (
151
+ [
152
+ new PrivateHeaderParameter ('test ' , true ),
153
+ new PublicHeaderParameter ('test2 ' , 'magento ' , 'value ' )
154
+ ]
155
+ ),
156
+ new JwsHeader (
157
+ [
158
+ new PrivateHeaderParameter ('test3 ' , true ),
159
+ new PublicHeaderParameter ('test4 ' , 'magento ' , 'value-another ' )
160
+ ]
161
+ )
162
+ ],
163
+ new ClaimsPayload ([
164
+ new Issuer ('magento.com ' ),
165
+ new JwtId (),
166
+ new Subject ('stuff ' )
167
+ ]),
168
+ [
169
+ new JwsHeader ([new PrivateHeaderParameter ('public ' , 'header1 ' )]),
170
+ new JwsHeader ([new PrivateHeaderParameter ('public2 ' , 'header ' )])
171
+ ]
172
+ );
173
+
139
174
$ rsaPrivateResource = openssl_pkey_new (['private_key_bites ' => 512 , 'private_key_type ' => OPENSSL_KEYTYPE_RSA ]);
140
175
if ($ rsaPrivateResource === false ) {
141
176
throw new \RuntimeException ('Failed to create RSA keypair ' );
142
177
}
143
178
$ rsaPublic = openssl_pkey_get_details ($ rsaPrivateResource )['key ' ];
144
- if (!openssl_pkey_export ($ rsaPrivateResource , $ rsaPrivate )) {
179
+ if (!openssl_pkey_export ($ rsaPrivateResource , $ rsaPrivate, ' pass ' )) {
145
180
throw new \RuntimeException ('Failed to read RSA private key ' );
146
181
}
147
182
openssl_free_key ($ rsaPrivateResource );
183
+ $ sharedSecret = random_bytes (128 );
148
184
149
185
return [
150
186
'jws-HS256 ' => [
@@ -158,29 +194,85 @@ public function getTokenVariants(): array
158
194
[$ enc ]
159
195
],
160
196
'jws-HS512 ' => [
161
- $ flatJwsWithUnprotectedHeader ,
197
+ $ jwsWithUnprotectedHeader ,
162
198
$ enc = new JwsSignatureJwks ($ jwkFactory ->createHs512 (random_bytes (128 ))),
163
199
[$ enc ]
164
200
],
165
201
'jws-RS256 ' => [
166
202
$ flatJws ,
167
- new JwsSignatureJwks ($ jwkFactory ->createSignRs256 ($ rsaPrivate , null )),
203
+ new JwsSignatureJwks ($ jwkFactory ->createSignRs256 ($ rsaPrivate , 'pass ' )),
204
+ [new JwsSignatureJwks ($ jwkFactory ->createVerifyRs256 ($ rsaPublic ))]
205
+ ],
206
+ 'jws-RS384 ' => [
207
+ $ flatJws ,
208
+ new JwsSignatureJwks ($ jwkFactory ->createSignRs384 ($ rsaPrivate , 'pass ' )),
209
+ [new JwsSignatureJwks ($ jwkFactory ->createVerifyRs384 ($ rsaPublic ))]
210
+ ],
211
+ 'jws-RS512 ' => [
212
+ $ jwsWithUnprotectedHeader ,
213
+ new JwsSignatureJwks ($ jwkFactory ->createSignRs512 ($ rsaPrivate , 'pass ' )),
214
+ [new JwsSignatureJwks ($ jwkFactory ->createVerifyRs512 ($ rsaPublic ))]
215
+ ],
216
+ 'jws-compact-multiple-signatures ' => [
217
+ $ compactJws ,
218
+ new JwsSignatureJwks (
219
+ new JwkSet (
220
+ [
221
+ $ jwkFactory ->createHs384 ($ sharedSecret ),
222
+ $ jwkFactory ->createSignRs256 ($ rsaPrivate , 'pass ' )
223
+ ]
224
+ )
225
+ ),
226
+ [
227
+ new JwsSignatureJwks (
228
+ new JwkSet (
229
+ [$ jwkFactory ->createHs384 ($ sharedSecret ), $ jwkFactory ->createVerifyRs256 ($ rsaPublic )]
230
+ )
231
+ )
232
+ ]
233
+ ],
234
+ 'jws-compact-multiple-signatures-one-read ' => [
235
+ $ compactJws ,
236
+ new JwsSignatureJwks (
237
+ new JwkSet (
238
+ [
239
+ $ jwkFactory ->createHs384 ($ sharedSecret ),
240
+ $ jwkFactory ->createSignRs256 ($ rsaPrivate , 'pass ' )
241
+ ]
242
+ )
243
+ ),
168
244
[new JwsSignatureJwks ($ jwkFactory ->createVerifyRs256 ($ rsaPublic ))]
169
245
]
170
246
];
171
247
}
172
248
173
- private function verifyHeader (HeaderInterface $ expected , HeaderInterface $ actual ): void
249
+ private function validateHeader (HeaderInterface $ expected , HeaderInterface $ actual ): void
174
250
{
175
- $ this -> assertTrue (
176
- count ( $ expected -> getParameters ()) <= count ( $ actual -> getParameters ())
177
- );
251
+ if ( count ( $ expected -> getParameters ()) > count ( $ actual -> getParameters ())) {
252
+ throw new \ InvalidArgumentException ( ' Missing header parameters ' );
253
+ }
178
254
foreach ($ expected ->getParameters () as $ parameter ) {
179
- $ this ->assertNotNull ($ actual ->getParameter ($ parameter ->getName ()));
180
- $ this ->assertEquals (
181
- $ parameter ->getValue (),
182
- $ actual ->getParameter ($ parameter ->getName ())->getValue ()
183
- );
255
+ if ($ actual ->getParameter ($ parameter ->getName ()) === null ) {
256
+ throw new \InvalidArgumentException ('Missing header parameters ' );
257
+ }
258
+ if ($ actual ->getParameter ($ parameter ->getName ())->getValue () !== $ parameter ->getValue ()) {
259
+ throw new \InvalidArgumentException ('Invalid header data ' );
260
+ }
261
+ }
262
+ }
263
+
264
+ private function verifyAgainstHeaders (array $ expected , HeaderInterface $ actual ): void
265
+ {
266
+ $ oneIsValid = false ;
267
+ foreach ($ expected as $ item ) {
268
+ try {
269
+ $ this ->validateHeader ($ item , $ actual );
270
+ $ oneIsValid = true ;
271
+ break ;
272
+ } catch (\InvalidArgumentException $ ex ) {
273
+ $ oneIsValid = false ;
274
+ }
184
275
}
276
+ $ this ->assertTrue ($ oneIsValid );
185
277
}
186
278
}
0 commit comments