@@ -264,9 +264,7 @@ my $jwt = encode_jwt(payload => {
264
264
--- no_error_log
265
265
[error]
266
266
267
-
268
-
269
- === TEST 2: JWT verification fails when no alg is present in the jwk to match against jwt.header.alg
267
+ === TEST 6: JWT verification does not fail when no alg is present in the jwk to match against jwt.header.alg
270
268
--- configuration env eval
271
269
use JSON qw(to_json);
272
270
@@ -303,7 +301,7 @@ to_json({
303
301
}
304
302
}
305
303
--- request: GET /test
306
- --- error_code: 403
304
+ --- error_code: 200
307
305
--- more_headers eval
308
306
use Crypt::JWT qw(encode_jwt);
309
307
my $jwt = encode_jwt(payload => {
@@ -313,5 +311,132 @@ my $jwt = encode_jwt(payload => {
313
311
iss => 'https://example.com/auth/realms/apicast',
314
312
exp => time + 3600 }, key => \$::private_key, alg => 'RS256', extra_headers => { kid => 'somekid' });
315
313
"Authorization: Bearer $jwt"
314
+ --- no_error_log
315
+
316
+ === TEST 7: JWT verification fails when jwk.alg exists AND does not match jwt.header.alg
317
+ (see THREESCALE-8249 for steps to generate tampered JWT. rsa.pub from fixtures used to sign)
318
+ --- configuration env eval
319
+ use JSON qw(to_json);
320
+
321
+ to_json({
322
+ services => [{
323
+ id => 42,
324
+ backend_version => 'oauth',
325
+ backend_authentication_type => 'provider_key',
326
+ backend_authentication_value => 'fookey',
327
+ proxy => {
328
+ authentication_method => 'oidc',
329
+ oidc_issuer_endpoint => 'https://example.com/auth/realms/apicast',
330
+ api_backend => "http://test:$TEST_NGINX_SERVER_PORT/",
331
+ proxy_rules => [
332
+ { pattern => '/', http_method => 'GET', metric_system_name => 'hits', delta => 1 }
333
+ ]
334
+ }
335
+ }],
336
+ oidc => [{
337
+ issuer => 'https://example.com/auth/realms/apicast',
338
+ config => { id_token_signing_alg_values_supported => [ 'RS256', 'HS256' ] },
339
+ keys => { somekid => { pem => $::public_key, alg => 'RS256' } },
340
+ }]
341
+ });
342
+ --- upstream
343
+ location /test {
344
+ echo "yes";
345
+ }
346
+ --- backend
347
+ location = /transactions/oauth_authrep.xml {
348
+ content_by_lua_block {
349
+ local expected = "provider_key=fookey&service_id=42&usage%5Bhits%5D=1&app_id=appid"
350
+ require('luassert').same(ngx.decode_args(expected), ngx.req.get_uri_args(0))
351
+ }
352
+ }
353
+ --- request: GET /test
354
+ --- error_code: 403
355
+ --- more_headers eval
356
+ use Crypt::JWT qw(encode_jwt);
357
+ my $jwt = 'eyJraWQiOiJzb21la2lkIiwiYWxnIjoiSFMyNTYifQ.'.
358
+ 'eyJleHAiOjcxNzA1MzE2NDMwLCJhenAiOiJhcHBpZCIsInN1YiI6In'.
359
+ 'NvbWVvbmUiLCJhdWQiOiJzb21ldGhpbmciLCJpc3MiOiJodHRwczov'.
360
+ 'L2V4YW1wbGUuY29tL2F1dGgvcmVhbG1zL2FwaWNhc3QifQ.1rFq5QN'.
361
+ 'b99W6aqQjsx7GJGLDpdkDLI6-huZLzMAmxGQ';
362
+ "Authorization: Bearer $jwt"
316
363
--- error_log
317
364
[jwt] alg mismatch
365
+
366
+ === TEST 8: Token was signed by a different key
367
+ --- configuration env eval
368
+ use JSON qw(to_json);
369
+
370
+ to_json({
371
+ services => [{
372
+ id => 42,
373
+ backend_version => 'oauth',
374
+ backend_authentication_type => 'provider_key',
375
+ backend_authentication_value => 'fookey',
376
+ proxy => {
377
+ authentication_method => 'oidc',
378
+ oidc_issuer_endpoint => 'https://example.com/auth/realms/a',
379
+ api_backend => "http://test:$TEST_NGINX_SERVER_PORT/",
380
+ proxy_rules => [
381
+ { pattern => '/', http_method => 'GET', metric_system_name => 'hits', delta => 1 }
382
+ ]
383
+ }
384
+ }],
385
+ oidc => [{
386
+ issuer => 'https://example.com/auth/realms/a',
387
+ config => { id_token_signing_alg_values_supported => [ 'RS256' ] },
388
+ keys => { somekid => { pem => $::public_key, alg => 'RS256' } },
389
+ }]
390
+ });
391
+ --- request: GET /test
392
+ --- error_code: 403
393
+ --- more_headers eval
394
+ use Crypt::JWT qw(encode_jwt);
395
+ my $jwt = encode_jwt(payload => {
396
+ aud => 'something',
397
+ azp => 'appid',
398
+ sub => 'someone',
399
+ iss => 'https://example.com/auth/realms/b',
400
+ exp => time + 3600 }, key => \$::private_key, alg => 'RS256', extra_headers => { kid => 'otherkid' });
401
+ "Authorization: Bearer $jwt"
402
+ --- error_log
403
+ [jwk] not found, token might belong to a different realm
404
+
405
+ === TEST 9: Token was signed by a different issuer
406
+ --- configuration env eval
407
+ use JSON qw(to_json);
408
+
409
+ to_json({
410
+ services => [{
411
+ id => 42,
412
+ backend_version => 'oauth',
413
+ backend_authentication_type => 'provider_key',
414
+ backend_authentication_value => 'fookey',
415
+ proxy => {
416
+ authentication_method => 'oidc',
417
+ oidc_issuer_endpoint => 'https://example.com/auth/realms/apicast',
418
+ api_backend => "http://test:$TEST_NGINX_SERVER_PORT/",
419
+ proxy_rules => [
420
+ { pattern => '/', http_method => 'GET', metric_system_name => 'hits', delta => 1 }
421
+ ]
422
+ }
423
+ }],
424
+ oidc => [{
425
+ issuer => 'https://example.com/auth/realms/apicast',
426
+ config => { id_token_signing_alg_values_supported => [ 'RS256' ] },
427
+ keys => { somekid => { pem => $::public_key, alg => 'RS256' } },
428
+ }]
429
+ });
430
+ --- request: GET /test
431
+ --- error_code: 403
432
+ --- more_headers eval
433
+ use Crypt::JWT qw(encode_jwt);
434
+ my $jwt = encode_jwt(payload => {
435
+ aud => 'something',
436
+ azp => 'appid',
437
+ sub => 'someone',
438
+ iss => 'unexpected_issuer',
439
+ exp => time + 3600 }, key => \$::private_key, alg => 'RS256', extra_headers => { kid => 'somekid' });
440
+ "Authorization: Bearer $jwt"
441
+ --- error_log eval
442
+ [ qr/Claim 'iss' \('unexpected_issuer'\) returned failure/ ]
0 commit comments