Skip to content

Commit

Permalink
support multiple authenticators for apis
Browse files Browse the repository at this point in the history
  • Loading branch information
thiagobustamante committed Feb 5, 2018
1 parent d8d49f3 commit 11dc2ea
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 21 deletions.
62 changes: 44 additions & 18 deletions src/authentication/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,32 @@ export class ApiAuth {

authentication(apiRouter: express.Router, apiKey: string, api: ApiConfig, gatewayFeatures: ApiFeaturesConfig) {
const path: string = api.path;
let authentication: ApiAuthenticationConfig = api.authentication;
try {
authentication = this.resolveReferences(authentication, gatewayFeatures);
const authStrategy: auth.Strategy = this.middlewareLoader.loadMiddleware('authentication/strategy', authentication.strategy);
if (!authStrategy) {
this.logger.error('Error configuring authenticator. Invalid Strategy');
} else {
auth.use(apiKey, authStrategy);
const authentications: Array<ApiAuthenticationConfig> = this.sortMiddlewares(api.authentication, path);

const authenticator = auth.authenticate(apiKey, { session: false, failWithError: true });
if (authentication.group) {
this.createAuthenticatorForGroup(apiRouter, api, authentication, authenticator);
authentications.forEach((authentication: ApiAuthenticationConfig, index: number) => {
try {
authentication = this.resolveReferences(authentication, gatewayFeatures);
const authStrategy: auth.Strategy = this.middlewareLoader.loadMiddleware('authentication/strategy', authentication.strategy);
if (!authStrategy) {
this.logger.error('Error configuring authenticator. Invalid Strategy');
} else {
this.createAuthenticator(apiRouter, api, authentication, authenticator);
}
auth.use(`${apiKey}_${index}`, authStrategy);

const authenticator = auth.authenticate(`${apiKey}_${index}`, { session: false, failWithError: true });
if (authentication.group) {
this.createAuthenticatorForGroup(apiRouter, api, authentication, authenticator);
} else {
this.createAuthenticator(apiRouter, api, authentication, authenticator);
}

if (this.logger.isDebugEnabled) {
this.logger.debug(`Authentication Strategy [${this.middlewareLoader.getId(authentication.strategy)}] configured for path [${path}]`);
if (this.logger.isDebugEnabled) {
this.logger.debug(`Authentication Strategy [${this.middlewareLoader.getId(authentication.strategy)}] configured for path [${path}]`);
}
}
} catch (e) {
this.logger.error(`Error configuring Authentication Strategy [${this.middlewareLoader.getId(authentication.strategy)}] for path [${path}]`, e);
}
} catch (e) {
this.logger.error(`Error configuring Authentication Strategy [${this.middlewareLoader.getId(authentication.strategy)}] for path [${path}]`, e);
}
});
}

private resolveReferences(authentication: ApiAuthenticationConfig, features: ApiFeaturesConfig) {
Expand Down Expand Up @@ -132,4 +135,27 @@ export class ApiAuth {

return null;
}

private sortMiddlewares(middlewares: Array<ApiAuthenticationConfig>, path: string): Array<ApiAuthenticationConfig> {
const generalMiddlewares = _.filter(middlewares, (value) => {
if (value.group) {
return true;
}
return false;
});

if (generalMiddlewares.length > 1) {
this.logger.error(`Invalid authentication configuration for api [${path}]. Conflicting configurations for default group`);
return [];
}

if (generalMiddlewares.length > 0) {
const index = middlewares.indexOf(generalMiddlewares[0]);
if (index < middlewares.length - 1) {
const gen = middlewares.splice(index, 1);
middlewares.push(gen[0]);
}
}
return middlewares;
}
}
4 changes: 2 additions & 2 deletions src/config/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export interface ApiConfig {
/**
* Configuration for API authentication.
*/
authentication?: ApiAuthenticationConfig;
authentication?: Array<ApiAuthenticationConfig>;
/**
* Configuration for API cache.
*/
Expand Down Expand Up @@ -97,7 +97,7 @@ export interface ApiConfig {
}

export let apiConfigValidatorSchema = Joi.object().keys({
authentication: apiAuthenticationValidatorSchema,
authentication: Joi.alternatives([Joi.array().items(apiAuthenticationValidatorSchema), apiAuthenticationValidatorSchema]),
cache: Joi.alternatives([Joi.array().items(apiCacheConfigValidatorSchema), apiCacheConfigValidatorSchema]),
circuitBreaker: Joi.alternatives([Joi.array().items(apiCircuitBreakerConfigValidatorSchema), apiCircuitBreakerConfigValidatorSchema]),
cors: Joi.alternatives([Joi.array().items(apiCorsConfigSchema), apiCorsConfigSchema]),
Expand Down
5 changes: 4 additions & 1 deletion src/service/redis/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,12 @@ export class RedisApiService implements ApiService {
});
});
}
castArray(api, 'authentication.group'); // TODO aceitar array de autenticators
castArray(api, 'proxy.target.allow');
castArray(api, 'proxy.target.deny');
if (_.has(api, 'authentication')) {
castArray(api, 'authentication');
api.authentication.forEach(config => castArray(config, 'group'));
}
if (_.has(api, 'cache')) {
castArray(api, 'cache');
api.cache.forEach(config => {
Expand Down

0 comments on commit 11dc2ea

Please sign in to comment.