From d7fecad45d611cef3a20b0d813e9f6e165be6787 Mon Sep 17 00:00:00 2001 From: Thomas Thomsen Date: Mon, 19 May 2025 06:58:55 -0400 Subject: [PATCH 1/4] ready --- .../src/lib/jwks-validation-handler.ts | 60 ++++++++++++++----- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts b/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts index 227666c8..db989053 100644 --- a/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts +++ b/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts @@ -1,8 +1,10 @@ import * as rs from 'jsrsasign'; import { AbstractValidationHandler, + DateTimeProvider, ValidationParams, } from 'angular-oauth2-oidc'; +import { Injector } from '@angular/core'; /** * Validates the signature of an id_token against one @@ -11,6 +13,12 @@ import { * This jwks can be provided by the discovery document. */ export class JwksValidationHandler extends AbstractValidationHandler { + constructor( + private injector?: Injector, + private validationOptions?: () => object + ) { + super(); + } /** * Allowed algorithms */ @@ -50,17 +58,17 @@ export class JwksValidationHandler extends AbstractValidationHandler { // console.debug('validateSignature: retry', retry); - let kid: string = params.idTokenHeader['kid']; - let keys: object[] = params.jwks['keys']; + const kid: string = params.idTokenHeader['kid']; + const keys: object[] = params.jwks['keys']; let key: object; - let alg = params.idTokenHeader['alg']; + const alg = params.idTokenHeader['alg']; if (kid) { key = keys.find((k) => k['kid'] === kid /* && k['use'] === 'sig' */); } else { - let kty = this.alg2kty(alg); - let matchingKeys = keys.filter( + const kty = this.alg2kty(alg); + const matchingKeys = keys.filter( (k) => k['kty'] === kty && k['use'] === 'sig' ); @@ -71,7 +79,7 @@ export class JwksValidationHandler extends AbstractValidationHandler { return Promise.reject(error); }*/ if (matchingKeys.length > 1) { - let error = + const error = 'More than one matching key found. Please specify a kid in the id_token header.'; console.error(error); return Promise.reject(error); @@ -88,13 +96,13 @@ export class JwksValidationHandler extends AbstractValidationHandler { } if (!key && retry && !kid) { - let error = 'No matching key found.'; + const error = 'No matching key found.'; console.error(error); return Promise.reject(error); } if (!key && retry && kid) { - let error = + const error = 'expected key not found in property jwks. ' + 'This property is most likely loaded with the ' + 'discovery document. ' + @@ -105,16 +113,18 @@ export class JwksValidationHandler extends AbstractValidationHandler { return Promise.reject(error); } - let keyObj = rs.KEYUTIL.getKey(key); - let validationOptions = { + const keyObj = this.getKey(key); + const customValidationOptions = { + ...(this.validationOptions ? this.validationOptions() : {}), + }; + const validationOptions = { alg: this.allowedAlgorithms, gracePeriod: this.gracePeriodInSec, + verifyAt: this.verifyAt, + ...customValidationOptions, }; - let isValid = rs.KJUR.jws.JWS.verifyJWT( - params.idToken, - keyObj, - validationOptions - ); + + const isValid = this.verifyJWT(params.idToken, keyObj, validationOptions); if (isValid) { return Promise.resolve(); @@ -123,7 +133,15 @@ export class JwksValidationHandler extends AbstractValidationHandler { } } - private alg2kty(alg: string) { + getKey(key: object) { + return rs.KEYUTIL.getKey(key); + } + + verifyJWT(idToken: string, keyObj: object, validationOptions: object) { + return rs.KJUR.jws.JWS.verifyJWT(idToken, keyObj, validationOptions); + } + + alg2kty(alg: string) { switch (alg.charAt(0)) { case 'R': return 'RSA'; @@ -150,4 +168,14 @@ export class JwksValidationHandler extends AbstractValidationHandler { } return result; } + + private get dateTimeProvider() { + return this.injector?.get(DateTimeProvider); + } + + private get verifyAt() { + const now = this.dateTimeProvider?.new() || new Date(); + const verifyAt = Math.floor(now.getTime() / 1000); + return verifyAt; + } } From 51ffd4c6284fefd6dab4d34d89a35e188e045752 Mon Sep 17 00:00:00 2001 From: Thomas Thomsen Date: Mon, 19 May 2025 07:09:51 -0400 Subject: [PATCH 2/4] expose rs --- .../src/lib/jwks-validation-handler.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts b/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts index db989053..806cb1df 100644 --- a/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts +++ b/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts @@ -134,11 +134,11 @@ export class JwksValidationHandler extends AbstractValidationHandler { } getKey(key: object) { - return rs.KEYUTIL.getKey(key); + return this.rs.KEYUTIL.getKey(key); } verifyJWT(idToken: string, keyObj: object, validationOptions: object) { - return rs.KJUR.jws.JWS.verifyJWT(idToken, keyObj, validationOptions); + return this.rs.KJUR.jws.JWS.verifyJWT(idToken, keyObj, validationOptions); } alg2kty(alg: string) { @@ -169,6 +169,10 @@ export class JwksValidationHandler extends AbstractValidationHandler { return result; } + get rs() { + return rs; + } + private get dateTimeProvider() { return this.injector?.get(DateTimeProvider); } From a9ecf0d23c7571c65aea56fb17e1086a3262a3da Mon Sep 17 00:00:00 2001 From: Thomas Thomsen Date: Mon, 19 May 2025 07:23:40 -0400 Subject: [PATCH 3/4] verify at --- .../src/lib/jwks-validation-handler.ts | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts b/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts index 806cb1df..d24173b0 100644 --- a/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts +++ b/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts @@ -13,10 +13,7 @@ import { Injector } from '@angular/core'; * This jwks can be provided by the discovery document. */ export class JwksValidationHandler extends AbstractValidationHandler { - constructor( - private injector?: Injector, - private validationOptions?: () => object - ) { + constructor(private injector?: Injector) { super(); } /** @@ -114,14 +111,10 @@ export class JwksValidationHandler extends AbstractValidationHandler { } const keyObj = this.getKey(key); - const customValidationOptions = { - ...(this.validationOptions ? this.validationOptions() : {}), - }; const validationOptions = { alg: this.allowedAlgorithms, gracePeriod: this.gracePeriodInSec, verifyAt: this.verifyAt, - ...customValidationOptions, }; const isValid = this.verifyJWT(params.idToken, keyObj, validationOptions); @@ -153,17 +146,17 @@ export class JwksValidationHandler extends AbstractValidationHandler { } calcHash(valueToHash: string, algorithm: string): Promise { - let hashAlg = new rs.KJUR.crypto.MessageDigest({ alg: algorithm }); - let result = hashAlg.digestString(valueToHash); - let byteArrayAsString = this.toByteArrayAsString(result); + const hashAlg = new rs.KJUR.crypto.MessageDigest({ alg: algorithm }); + const result = hashAlg.digestString(valueToHash); + const byteArrayAsString = this.toByteArrayAsString(result); return Promise.resolve(byteArrayAsString); } toByteArrayAsString(hexString: string) { let result = ''; for (let i = 0; i < hexString.length; i += 2) { - let hexDigit = hexString.charAt(i) + hexString.charAt(i + 1); - let num = parseInt(hexDigit, 16); + const hexDigit = hexString.charAt(i) + hexString.charAt(i + 1); + const num = parseInt(hexDigit, 16); result += String.fromCharCode(num); } return result; From cdf52556f6ccc08d8ed12f858c3f8c29d7a2efb6 Mon Sep 17 00:00:00 2001 From: Thomas Thomsen Date: Fri, 23 May 2025 00:36:17 -0400 Subject: [PATCH 4/4] no floor --- .../angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts b/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts index d24173b0..9f60a4c5 100644 --- a/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts +++ b/projects/angular-oauth2-oidc-jwks/src/lib/jwks-validation-handler.ts @@ -172,7 +172,7 @@ export class JwksValidationHandler extends AbstractValidationHandler { private get verifyAt() { const now = this.dateTimeProvider?.new() || new Date(); - const verifyAt = Math.floor(now.getTime() / 1000); + const verifyAt = now.getTime() / 1000; return verifyAt; } }