File

projects/lib/src/token-validation/validation-handler.ts

Description

Interface for Handlers that are hooked in to validate tokens.

Index

Methods

Methods

Public validateAtHash
validateAtHash(validationParams: ValidationParams)

Validates the at_hash in an id_token against the received access_token.

Parameters :
Name Type Optional
validationParams ValidationParams no
Returns : boolean
Public validateSignature
validateSignature(validationParams: ValidationParams)

Validates the signature of an id_token.

Parameters :
Name Type Optional
validationParams ValidationParams no
Returns : Promise<any>
export interface ValidationParams {
  idToken: string;
  accessToken: string;
  idTokenHeader: object;
  idTokenClaims: object;
  jwks: object;
  loadKeys: () => Promise<object>;
}

/**
 * Interface for Handlers that are hooked in to
 * validate tokens.
 */
export abstract class ValidationHandler {
  /**
   * Validates the signature of an id_token.
   */
  public abstract validateSignature(
    validationParams: ValidationParams
  ): Promise<any>;

  /**
   * Validates the at_hash in an id_token against the received access_token.
   */
  public abstract validateAtHash(validationParams: ValidationParams): boolean;
}

/**
 * This abstract implementation of ValidationHandler already implements
 * the method validateAtHash. However, to make use of it,
 * you have to override the method calcHash.
 */
export abstract class AbstractValidationHandler implements ValidationHandler {
  /**
   * Validates the signature of an id_token.
   */
  abstract validateSignature(validationParams: ValidationParams): Promise<any>;

  /**
   * Validates the at_hash in an id_token against the received access_token.
   */
  validateAtHash(params: ValidationParams): boolean {
    let hashAlg = this.inferHashAlgorithm(params.idTokenHeader);

    let tokenHash = this.calcHash(params.accessToken, hashAlg); // sha256(accessToken, { asString: true });

    let leftMostHalf = tokenHash.substr(0, tokenHash.length / 2);

    let tokenHashBase64 = btoa(leftMostHalf);

    let atHash = tokenHashBase64
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=/g, '');
    let claimsAtHash = params.idTokenClaims['at_hash'].replace(/=/g, '');

    if (atHash !== claimsAtHash) {
      console.error('exptected at_hash: ' + atHash);
      console.error('actual at_hash: ' + claimsAtHash);
    }

    return atHash === claimsAtHash;
  }

  /**
   * Infers the name of the hash algorithm to use
   * from the alg field of an id_token.
   *
   * @param jwtHeader the id_token's parsed header
   */
  protected inferHashAlgorithm(jwtHeader: object): string {
    let alg: string = jwtHeader['alg'];

    if (!alg.match(/^.S[0-9]{3}$/)) {
      throw new Error('Algorithm not supported: ' + alg);
    }

    return 'sha' + alg.substr(2);
  }

  /**
   * Calculates the hash for the passed value by using
   * the passed hash algorithm.
   *
   * @param valueToHash
   * @param algorithm
   */
  protected abstract calcHash(valueToHash: string, algorithm: string): string;
}

results matching ""

    No results matching ""