I'm trying to write a validator class using passport-azure-ad to validate all the request to my APIs.
I have extended the PassportStrategy class and configured it as a global guard. Everything working fine. But now I have requirement to validate the request from different UI application from various domains. The problem here is clientId and tenantId will be different for each UI application hence the token they are passing in the header needs to validate against corresponding clientId and identityMetadata.
every request will have a param called appname in the header and based on the appname I need to fetch the passport configuration from the database for each application.
Is there any better way to implement this approach.
Below is the PassportStrategy class I have written
import { AuthGuard, PassportStrategy } from '@nestjs/passport';
import { BearerStrategy } from 'passport-azure-ad';
import { Injectable } from '@nestjs/common';
@Injectable()
export class AzureADStrategy extends PassportStrategy(BearerStrategy, 'azure-ad-bearer') {
constructor(dbService: DbService) {
//const appName = request.headers['appname']
//const metaData = await dbService.getTokenMetaData(appName)
super({
identityMetadata: metaData.identity,
jwtIssuer: metaData.issuer,
clientID: metaData.clientId,
validateIssuer: true,
passReqToCallback: false,
loggingLevel: 'info',
loggingNoPII: false
});
}
async validate(payload: any): Promise<any> {
return payload;
}
}
export const AzureADGuard = AuthGuard('azure-ad-bearer');
In the above code the two commented line is my logic to implement,
- But how the request can be accessed in the constructor ?
- super() should be the first call in the constructor in that case how can i call my dbService to get data from DB ?
Your question is a bit unclear, but I will try to show the standard practice (in theory) for using passport strategies.
You don't access things from the constructor except for any configService you may have implemented for it. You will want to implement that and then grab environment variables from it such as identity, issuer etc (your "metadata"). See NestJs docs here for example of implementation of configuration service
Any sort of side-effect (like calling redis, or sql db or similar) should be done inside your validate() method. Check exactly what parameters (payload) that method receives and use those to verify and validate the incoming request against your personal logic.
Good luck!