Commit 9918bdf7 authored by Diego Molteni's avatar Diego Molteni
Browse files

Merge branch 'slb/dm3/token-exchange-cache' into 'master'

feat: added cache layer for exchanged tokens & multi audience in the impersonation token

See merge request !218
parents 3acf2ee9 f7a3d7d2
Pipeline #67749 failed with stages
in 12 minutes and 1 second
......@@ -462,7 +462,7 @@ The following software have components provided under the terms of this license:
- content-disposition (from https://www.npmjs.com/package/content-disposition)
- content-type (from https://www.npmjs.com/package/content-type)
- cookie (from https://www.npmjs.com/package/cookie)
- cookie-signature (from https://github.com/visionmedia/node-cookie-signature)
- cookie-signature (from https://www.npmjs.com/package/cookie-signature)
- copyfiles (from https://www.npmjs.com/package/copyfiles)
- core-util-is (from https://www.npmjs.com/package/core-util-is)
- cors (from https://www.npmjs.com/package/cors)
......@@ -495,7 +495,7 @@ The following software have components provided under the terms of this license:
- dot-prop (from https://www.npmjs.com/package/dot-prop)
- duplexify (from https://www.npmjs.com/package/duplexify)
- ecc-jsbn (from https://www.npmjs.com/package/ecc-jsbn)
- ee-first (from https://github.com/jonathanong/ee-first)
- ee-first (from https://www.npmjs.com/package/ee-first)
- emoji-regex (from https://www.npmjs.com/package/emoji-regex)
- enabled (from https://www.npmjs.com/package/enabled)
- encodeurl (from https://www.npmjs.com/package/encodeurl)
......@@ -646,7 +646,7 @@ The following software have components provided under the terms of this license:
- map-obj (from https://www.npmjs.com/package/map-obj)
- media-typer (from https://github.com/jshttp/media-typer)
- merge-descriptors (from https://www.npmjs.com/package/merge-descriptors)
- methods (from https://github.com/jshttp/methods)
- methods (from https://www.npmjs.com/package/methods)
- mime (from https://www.npmjs.com/package/mime)
- mime (from https://www.npmjs.com/package/mime)
- mime-db (from https://www.npmjs.com/package/mime-db)
......@@ -693,7 +693,7 @@ The following software have components provided under the terms of this license:
- object.assign (from https://www.npmjs.com/package/object.assign)
- object.assign (from https://www.npmjs.com/package/object.assign)
- object.getownpropertydescriptors (from https://www.npmjs.com/package/object.getownpropertydescriptors)
- on-finished (from https://github.com/jshttp/on-finished)
- on-finished (from https://www.npmjs.com/package/on-finished)
- once (from https://github.com/isaacs/once#readme)
- one-time (from https://www.npmjs.com/package/one-time)
- onetime (from https://www.npmjs.com/package/onetime)
......
......@@ -14,17 +14,17 @@
// limitations under the License.
// ============================================================================
import { createHash } from 'crypto';
import { Config } from '../cloud';
import { DESCompliance, DESUtils } from '../dataecosystem';
import { ImpersonationTokenContextModel, ImpersonationTokenModel } from '../services/impersonation_token/model';
import { ImpTokenDAO } from '../services/imptoken';
import { AppsDAO } from '../services/svcapp/dao';
import { TenantModel } from '../services/tenant';
import { ITenantModel } from '../services/tenant/model';
import { Cache, Error, Utils } from '../shared';
import { AuthGroups } from './groups';
import { createHash } from 'crypto';
import { ImpersonationTokenContextModel, ImpersonationTokenModel } from '../services/impersonation_token/model';
import { ImpersonationTokenHandler } from '../services/impersonation_token/handler';
import { ITenantModel } from '../services/tenant/model';
// ===============================================================================================
// This class is used to register all auth provider
......@@ -65,6 +65,7 @@ export class AuthProviderFactoryBuilder {
// ===============================================================================================
export interface IAuthProvider {
generateAuthCredential(): Promise<any>;
generateScopedAuthCredential(scopes: string[]): Promise<any>;
convertToImpersonationTokenModel(credential: any): ImpersonationTokenModel;
getClientID(): string;
getClientSecret(): string;
......@@ -73,6 +74,7 @@ export interface IAuthProvider {
export abstract class AbstractAuthProvider implements IAuthProvider {
public abstract generateAuthCredential(): Promise<any>;
public abstract generateScopedAuthCredential(scopes: string[]): Promise<any>;
public abstract convertToImpersonationTokenModel(credential: any): ImpersonationTokenModel;
public abstract getClientID(): string;
public abstract getClientSecret(): string;
......
......@@ -26,6 +26,11 @@ export class GenericAuthProvider extends AbstractAuthProvider {
'The required feature is not supported, the credential auth provider has not been found.'));
}
public generateScopedAuthCredential(scopes: string[]): Promise<any> {
throw (Error.make(Error.Status.NOT_IMPLEMENTED,
'The required feature is not supported, the credential auth provider has not been found.'));
}
public convertToImpersonationTokenModel(credential: any): ImpersonationTokenModel {
throw (Error.make(Error.Status.NOT_IMPLEMENTED,
'The required feature is not supported, the credential auth provider has not been found.'));
......@@ -46,4 +51,4 @@ export class GenericAuthProvider extends AbstractAuthProvider {
'The required feature is not supported, the credential auth provider has not been found.'));
}
}
\ No newline at end of file
}
......@@ -26,7 +26,7 @@ import YAML from 'yamljs';
import { AuthProviderFactory } from '../auth';
import { Config, LoggerFactory } from '../cloud';
import { ServiceRouter } from '../services';
import { Error, Feature, FeatureFlags, Response, Utils } from '../shared';
import { Cache, Error, Feature, FeatureFlags, Response, Utils } from '../shared';
......@@ -41,6 +41,8 @@ export class Server {
private httpServer: import('http').Server;
private httpsServer: import('https').Server;
private static _exchangedTokenCache: Cache<string>;
private corsOptions = {
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
preflightContinue: false,
......@@ -127,10 +129,35 @@ export class Server {
// If required, exchange the caller credentials to include the DE target audience
if (Config.ENABLE_DE_TOKEN_EXCHANGE) {
if (Config.DES_TARGET_AUDIENCE) {
// init the cache
if (!Server._exchangedTokenCache) {
Server._exchangedTokenCache = new Cache<string>('tkex')
}
if (req.headers.authorization) {
req.headers.authorization = await AuthProviderFactory.build(
Config.SERVICE_AUTH_PROVIDER).exchangeCredentialAudience(
req.headers.authorization, Config.DES_TARGET_AUDIENCE);
// use the token signature as unique key
const originalAuthorizationHeaderSignature = req.headers.authorization.split('.')[2];
// check if in cache before
const cachedExchangedToken = await Server._exchangedTokenCache.get(
originalAuthorizationHeaderSignature);
if (cachedExchangedToken) {
req.headers.authorization = cachedExchangedToken;
} else {
// exchange the token
req.headers.authorization = await AuthProviderFactory.build(
Config.SERVICE_AUTH_PROVIDER).exchangeCredentialAudience(
req.headers.authorization, Config.DES_TARGET_AUDIENCE);
// cache the exchanged credential for 5 minute
await Server._exchangedTokenCache.set(
originalAuthorizationHeaderSignature, req.headers.authorization, 300);
}
}
}
}
......
......@@ -117,10 +117,13 @@ export class ImpersonationTokenHandler {
}
// generate the impersonation token credential token (the auth credential)
const impersonationToken = AuthProviderFactory.build(
Config.SERVICE_AUTH_PROVIDER).convertToImpersonationTokenModel(
await AuthProviderFactory.build(
Config.SERVICE_AUTH_PROVIDER).generateAuthCredential());
const authProvider = AuthProviderFactory.build(Config.SERVICE_AUTH_PROVIDER);
const scopes = [authProvider.getClientID()];
if(Config.DES_TARGET_AUDIENCE) {
scopes.push(Config.DES_TARGET_AUDIENCE)
}
const impersonationToken = authProvider.convertToImpersonationTokenModel(
await authProvider.generateScopedAuthCredential(scopes));
// Build and sign the impersonation token context
const context = {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment