How to add passport-saml in nestjs?

Viewed 2058

I am doing an authentication with saml in nestjs I am using the passport-saml package I am directing the page to the microsoft login correctly but in the callback route I do not get the profile data, what I want is to make the person authenticate with saml and that after that a token bearer is generated in the system, so far as I mentioned before I have not been able to obtain the data of the user who starts the session.

auth.module.ts

import { AuthController } from './auth.controller';
import { Saml2Strategy } from './strategies/saml.strategy';
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';

@Module({
  controllers: [AuthController],
  providers: [AuthService, Saml2Strategy],
})
export class AuthModule {}

controller the route is get('saml'), It is addressing correctly, but when returning to the callback url I cannot obtain the data of the person. auth.controller.ts

import { Saml2Strategy } from './strategies/saml.strategy';
import {
  Controller,
  Get,
  Post,
  UseGuards,
  Res,
  Req,
  Request,
  Body,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiTags } from '@nestjs/swagger';
const passport = require('passport');
const SamlStrategy = require('passport-saml').Strategy;
import { ConfigSaml } from './../user/controllers/config';
const fs = require('fs');

@ApiTags('Auth')
@Controller('auth')
export class AuthController {
  public config: ConfigSaml;
  public userData: any;
  constructor() {
    this.config = new ConfigSaml();
  }
  @Get('saml')
  @UseGuards(AuthGuard('saml'))
  samlLogin() {
 
  }

  @Post('/callback')
  async callback(@Request() req, @Body() body: any) {
    if (req.isAuthenticated()) {
      console.log('autenticado');
    }
     }
}

saml.strategy.ts

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { passport } from 'passport';

var SamlStrategy = require('passport-saml').Strategy;
const fs = require('fs');

@Injectable()
export class Saml2Strategy extends PassportStrategy(SamlStrategy, 'saml') {
  constructor() {
    super({
      entryPoint: process.env.SAML_ENTRY_POINT,
      issuer: process.env.SAML_ISSUER,
      callbackUrl: process.env.SAML_CALLBACK_URL,
      cert: fs.readFileSync(
        process.cwd() +
          '/src/modules/auth/strategies/' +
          process.env.SAML_CERT ||
          process.cwd() + '/src/modules/auth/strategies/certificate.pem',
        'utf-8',
      ),
      function(profile, done) {
        console.log('profile in strategy', profile);
        return done(null, {
          id: profile.nameID,
          email:
            profile[
              'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'
            ],
          displayName:
            profile['http://schemas.microsoft.com/identity/claims/displayname'],
          firstName:
            profile[
              'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'
            ],
          lastName:
            profile[
              'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname'
            ],
        });
      },
    });
  }
}

1 Answers

It seems like an old query... and I guess over here you are trying to get the SAML response as a Profile object, which is provided by the passport-saml strategy

So to retrieve the SAML response as a Profile object you need to set the same guard in the callback API '@Post('/callback')' as well, which you have used in the '@Get('saml')' API which is

@UseGuards(AuthGuard('saml'))

So your updated code block will be:

import { Saml2Strategy } from './strategies/saml.strategy';
import {
  Controller,
  Get,
  Post,
  UseGuards,
  Res,
  Req,
  Request,
  Body,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiTags } from '@nestjs/swagger';
const passport = require('passport');
const SamlStrategy = require('passport-saml').Strategy;
import { ConfigSaml } from './../user/controllers/config';
const fs = require('fs');

@ApiTags('Auth')
@Controller('auth')
export class AuthController {
  public config: ConfigSaml;
  public userData: any;
  constructor() {
    this.config = new ConfigSaml();
  }
  @Get('saml')
  @UseGuards(AuthGuard('saml'))
  samlLogin() {
 
  }

  
  @Post('/callback')
  @UseGuards(AuthGuard('saml'))
  async callback(@Request() req, @Body() body: any) {
    if (req.isAuthenticated()) {
      console.log('autenticado');
    }
     }
}
Related