From 9463ac234a8ad5451a3337374f4702d16d6018b7 Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Thu, 7 May 2020 14:06:51 -0700 Subject: [PATCH] feat(authentication): add a middleware for authentication --- .../src/authentication.component.ts | 19 ++++++----- packages/authentication/src/keys.ts | 8 +++++ .../src/providers/auth-action.provider.ts | 32 +++++++++++++++++-- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/packages/authentication/src/authentication.component.ts b/packages/authentication/src/authentication.component.ts index f6d90fa8e3f2..5318f54cb5ca 100644 --- a/packages/authentication/src/authentication.component.ts +++ b/packages/authentication/src/authentication.component.ts @@ -3,23 +3,22 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -import {bind, Component, ContextTags, ProviderMap} from '@loopback/core'; +import {bind, Component, ContextTags} from '@loopback/core'; import {AuthenticationBindings} from './keys'; import { AuthenticateActionProvider, + AuthenticationMiddlewareProvider, AuthenticationStrategyProvider, AuthMetadataProvider, } from './providers'; @bind({tags: {[ContextTags.KEY]: AuthenticationBindings.COMPONENT}}) export class AuthenticationComponent implements Component { - providers?: ProviderMap; - - constructor() { - this.providers = { - [AuthenticationBindings.AUTH_ACTION.key]: AuthenticateActionProvider, - [AuthenticationBindings.STRATEGY.key]: AuthenticationStrategyProvider, - [AuthenticationBindings.METADATA.key]: AuthMetadataProvider, - }; - } + providers = { + [AuthenticationBindings.AUTH_ACTION.key]: AuthenticateActionProvider, + [AuthenticationBindings.STRATEGY.key]: AuthenticationStrategyProvider, + [AuthenticationBindings.METADATA.key]: AuthMetadataProvider, + [AuthenticationBindings.AUTHENTICATION_MIDDLEWARE + .key]: AuthenticationMiddlewareProvider, + }; } diff --git a/packages/authentication/src/keys.ts b/packages/authentication/src/keys.ts index aa1d47188d5b..465c8c121d08 100644 --- a/packages/authentication/src/keys.ts +++ b/packages/authentication/src/keys.ts @@ -5,6 +5,7 @@ import {BindingKey} from '@loopback/context'; import {MetadataAccessor} from '@loopback/metadata'; +import {Middleware} from '@loopback/rest'; import {SecurityBindings} from '@loopback/security'; import {AuthenticationComponent} from './authentication.component'; import { @@ -89,6 +90,13 @@ export namespace AuthenticationBindings { 'authentication.actions.authenticate', ); + /** + * Binding key for AUTHENTICATION_MIDDLEWARE + */ + export const AUTHENTICATION_MIDDLEWARE = BindingKey.create( + 'middleware.authentication', + ); + /** * Key used to inject authentication metadata, which is used to determine * whether a request requires authentication or not. diff --git a/packages/authentication/src/providers/auth-action.provider.ts b/packages/authentication/src/providers/auth-action.provider.ts index 413fe863bf3a..d873bc390a1b 100644 --- a/packages/authentication/src/providers/auth-action.provider.ts +++ b/packages/authentication/src/providers/auth-action.provider.ts @@ -3,8 +3,14 @@ // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT -import {Getter, inject, Provider, Setter} from '@loopback/context'; -import {Request, RedirectRoute} from '@loopback/rest'; +import {bind, Getter, inject, Provider, Setter} from '@loopback/context'; +import { + asMiddleware, + Middleware, + RedirectRoute, + Request, + RestTags, +} from '@loopback/rest'; import {SecurityBindings, UserProfile} from '@loopback/security'; import {AuthenticationBindings} from '../keys'; import { @@ -80,3 +86,25 @@ export class AuthenticateActionProvider implements Provider { } } } + +@bind( + asMiddleware({ + chain: RestTags.REST_MIDDLEWARE_CHAIN, + group: 'authentication', + requestDependencies: 'cors', + responseDependencies: 'findRoute', + }), +) +export class AuthenticationMiddlewareProvider implements Provider { + constructor( + @inject(AuthenticationBindings.AUTH_ACTION) + private authenticate: AuthenticateFn, + ) {} + + value(): Middleware { + return async (ctx, next) => { + await this.authenticate(ctx.request); + return next(); + }; + } +}