Search code examples
nestjs

NestJS - Combine multiple Guards and activate if one returns true


Is it possible to use multiple auth guards on a route (in my case basic and ldap auth). The route should be authenticated when one guard was successful.


Solution

  • Short answer: No, if you add more than one guard to a route, they all need to pass for the route to be able to activate.

    Long answer: What you are trying to accomplish is possible however by making your LDAP guard extend the basic one. If the LDAP specific logic succeeds, return true, otherwise return the result of the call to super.canActivate(). Then, in your controller, add either the basic or LDAP guard to your routes, but not both.

    basic.guard.ts

    export BasicGuard implements CanActivate {
      constructor(
          protected readonly reflector: Reflector
      ) {}
    
      async canActivate(context: ExecutionContext) {
         const request = context.switchToHttp().getRequest();
         if () {
            // Do some logic and return true if access is granted
            return true;
         }
    
        return false;
      }
    }
    

    ldap.guard.ts

    export LdapGuard extends BasicGuard implements CanActivate {
      constructor(
          protected readonly reflector: Reflector
      ) {
       super(reflector);
    }
    
      async canActivate(context: ExecutionContext) {
         const request = context.switchToHttp().getRequest();
         if () {
            // Do some logic and return true if access is granted
            return true;
         }
        
        // Basically if this guard is false then try the super.canActivate.  If its true then it would have returned already
        return await super.canActivate(context);
      }
    }
    

    For more information see this GitHub issue on the official NestJS repository.