Nestjs azure active directory and graphql - UseGuard

Viewed 991

Building an API with nestjs and graphql I want to implement Azure Active Directory for authorization. They provide a passport-azure-ad package with a strategy. It is working just fine when I add a nestjs guard to a REST endpoint, but with a GrapQL resolver it is throwing an error Cannot read property 'query' of undefined.

Nestjs docs give some hint, but I have no idea how to implement and make the graphql query available to the passport strategy.

My guard looks as follows:

import { Injectable } from '@nestjs/common';
import { PassportStrategy, AuthGuard } from '@nestjs/passport';
import { BearerStrategy } from 'passport-azure-ad';
import * as dotenv from 'dotenv';
dotenv.config();

const clientID = process.env.AZURE_AD_CLIENT_ID;
const tenantID = process.env.AZURE_AD_TENANT_ID;

/**
 * Extracts ID token from header and validates it.
 */
@Injectable()
export class AzureADStrategy extends PassportStrategy(
  BearerStrategy,
  'azure-ad',
) {
  constructor() {
    super({
      identityMetadata: `https://login.microsoftonline.com/${tenantID}/v2.0/.well-known/openid-configuration`,
      clientID,
    });
  }
  
  async validate(data) {
    console.log(data);
    return data;
  }
}

export const AzureADGuard = AuthGuard('azure-ad');

GraphQL config from app.module.ts

...
imports: [
 GraphQLModule.forRoot({
      autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
      sortSchema: true,
      context: ({ req }) => ({ req }),
    }),
...
1 Answers

The passport strategy is probably looking for the query parameter of request, which isn't immediately available from a GQL request. To fix this, you can make a custom guard that extends AuthGuard('azure-ad') and override the getRequest() method to return the incoming req object with the following method:

@Injectable()
export class AzureADGuard extends AuthGuard('azure-ad') {
  getRequest(context: ExecutionContext) {
    const gql = GqlExecutionContext.create(context);
    return gql.getContext().req;
  }
}
Related