187
187
</ li >
188
188
189
189
190
+ < li class ="chapter ">
191
+ < a data-type ="chapter-link " href ="../coverage.html " > < span class ="fa fa-tasks "> </ span > Documentation coverage</ a >
192
+ </ li >
190
193
191
194
192
195
</ ul >
366
369
</ li >
367
370
368
371
372
+ < li class ="chapter ">
373
+ < a data-type ="chapter-link " href ="../coverage.html " > < span class ="fa fa-tasks "> </ span > Documentation coverage</ a >
374
+ </ li >
369
375
370
376
371
377
</ ul >
@@ -455,6 +461,9 @@ <h6><b>Methods</b></h6>
455
461
< tr >
456
462
< td class ="col-md-4 ">
457
463
< ul class ="index-list ">
464
+ < li >
465
+ < span class ="modifier "> Private</ span > < a href ="#alg2kty "> alg2kty</ a >
466
+ </ li >
458
467
< li >
459
468
< a href ="#calcHash "> calcHash</ a >
460
469
</ li >
@@ -477,6 +486,39 @@ <h6><b>Methods</b></h6>
477
486
< h3 id ="methods ">
478
487
Methods
479
488
</ h3 >
489
+ < table class ="table table-sm table-bordered ">
490
+ < tbody >
491
+ < tr >
492
+ < td class ="col-md-4 ">
493
+ < a name ="alg2kty "> </ a >
494
+ < b > < span class ="modifier "> Private</ span > alg2kty</ b >
495
+ </ td >
496
+ </ tr >
497
+ < tr >
498
+ < td class ="col-md-4 ">
499
+ < span class ="modifier-icon method fa fa-play lock "> </ span >
500
+ < code > alg2kty(alg: < a href ="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/string " target ="_blank "> string</ a > )</ code >
501
+ </ td >
502
+ </ tr >
503
+
504
+
505
+ < tr >
506
+ < td class ="col-md-4 ">
507
+ < div class ="io-line "> Defined in < a href ="" data-line ="99 " class ="link-to-prism "> src/token-validation/jwks-validation-handler.ts:99</ a > </ div >
508
+ </ td >
509
+ </ tr >
510
+
511
+ < tr >
512
+ < td class ="col-md-4 ">
513
+
514
+ < div class ="io-description ">
515
+ < b > Returns : </ b > < code > "RSA" | "EC"</ code >
516
+
517
+ </ div >
518
+ </ td >
519
+ </ tr >
520
+ </ tbody >
521
+ </ table >
480
522
< table class ="table table-sm table-bordered ">
481
523
< tbody >
482
524
< tr >
@@ -494,7 +536,7 @@ <h3 id="methods">
494
536
495
537
< tr >
496
538
< td class ="col-md-4 ">
497
- < div class ="io-line "> Defined in < a href ="" data-line ="71 " class ="link-to-prism "> src/token-validation/jwks-validation-handler.ts:71 </ a > </ div >
539
+ < div class ="io-line "> Defined in < a href ="" data-line ="107 " class ="link-to-prism "> src/token-validation/jwks-validation-handler.ts:107 </ a > </ div >
498
540
</ td >
499
541
</ tr >
500
542
@@ -526,7 +568,7 @@ <h3 id="methods">
526
568
527
569
< tr >
528
570
< td class ="col-md-4 ">
529
- < div class ="io-line "> Defined in < a href ="" data-line ="78 " class ="link-to-prism "> src/token-validation/jwks-validation-handler.ts:78 </ a > </ div >
571
+ < div class ="io-line "> Defined in < a href ="" data-line ="114 " class ="link-to-prism "> src/token-validation/jwks-validation-handler.ts:114 </ a > </ div >
530
572
</ td >
531
573
</ tr >
532
574
@@ -551,7 +593,7 @@ <h3 id="methods">
551
593
</ tr >
552
594
< tr >
553
595
< td class ="col-md-4 ">
554
- < code > validateSignature(params: < a href ="../interfaces/ValidationParams.html "> ValidationParams</ a > )</ code >
596
+ < code > validateSignature(params: < a href ="../interfaces/ValidationParams.html "> ValidationParams</ a > , retry: < a href =" https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/boolean " target =" _blank " > boolean </ a > )</ code >
555
597
</ td >
556
598
</ tr >
557
599
@@ -686,7 +728,7 @@ <h3 id="inputs">
686
728
*/
687
729
gracePeriodInSec: number = 600;
688
730
689
- validateSignature(params: ValidationParams): Promise<any> {
731
+ validateSignature(params: ValidationParams, retry: boolean = false ): Promise<any> {
690
732
if (!params.idToken) throw new Error('Parameter idToken expected!');
691
733
if (!params.idTokenHeader) throw new Error('Parameter idTokenHandler expected.');
692
734
if (!params.jwks) throw new Error('Parameter jwks expected!');
@@ -695,23 +737,51 @@ <h3 id="inputs">
695
737
throw new Error('Array keys in jwks missing!');
696
738
}
697
739
740
+ console.debug('validateSignature: retry', retry);
741
+
698
742
let kid: string = params.idTokenHeader['kid'];
699
743
let keys: object[] = params.jwks['keys'];
700
744
let key: object;
701
745
702
- if (!kid && params.jwks['keys'].length > 1) {
703
- let error = 'Multiple keys but no kid in token!';
704
- console.error(error);
705
- return Promise.reject(error);
706
- }
707
- else if (!kid) {
708
- key = params.jwks['keys'][0];
746
+ let alg = params.idTokenHeader['alg'];
747
+
748
+ if (kid) {
749
+ key = keys.find(k => k['kid'] == kid && k['use'] == 'sig');
709
750
}
710
751
else {
711
- key = keys.find(k => k['kid'] == kid && k['use'] == 'sig');
752
+ let kty = this.alg2kty(alg)
753
+ let matchingKeys = keys.filter(k => k['kty'] == kty && k['use'] == 'sig');
754
+
755
+ /*
756
+ if (matchingKeys.length == 0) {
757
+ let error = 'No matching key found.';
758
+ console.error(error);
759
+ return Promise.reject(error);
760
+ }*/
761
+ if (matchingKeys.length > 1) {
762
+ let error = 'More than one matching key found. Please specify a kid in the id_token header.';
763
+ console.error(error);
764
+ return Promise.reject(error);
765
+ }
766
+ else if (matchingKeys.length == 1) {
767
+ key = matchingKeys[0];
768
+ }
712
769
}
713
770
714
- if (!key) {
771
+ if (!key && !retry && params.loadKeys) {
772
+ return params
773
+ .loadKeys()
774
+ .then(keys => params.jwks = keys)
775
+ .then(_ => this.validateSignature(params, true));
776
+ }
777
+
778
+ if (!key && retry && !kid) {
779
+ let error = 'No matching key found.';
780
+ console.error(error);
781
+ return Promise.reject(error);
782
+ }
783
+
784
+ if (!key && retry && kid) {
715
785
let error = 'expected key not found in property jwks. '
716
786
+ 'This property is most likely loaded with the '
717
787
+ 'discovery document. '
@@ -732,6 +802,14 @@ <h3 id="inputs">
732
802
}
733
803
}
734
804
805
+ private alg2kty(alg: string) {
806
+ switch(alg.charAt(0)) {
807
+ case 'R': return 'RSA';
808
+ case 'E': return 'EC';
809
+ default: throw new Error('Cannot infer kty from alg: ' + alg);
810
+ }
811
+ }
812
+
735
813
calcHash(valueToHash: string, algorithm: string): string {
736
814
let hashAlg = new rs.KJUR.crypto.MessageDigest({alg: algorithm});
737
815
let result = hashAlg.digestString(valueToHash);
0 commit comments