node.jsazuremicrosoft-graph-apisingle-sign-onpassport.js

Implementing Microsoft SSO with passport-azure-ad and without msal


I want to implement SSO sign up/sign in for Microsoft Azure AD B2C in NodeJS however, I want to create the user using Graph API. I'm using passport-azure-ad strategy. The process has to be custom because based on the user's info, a QR code is to be generated. So I just need the user object and the token.

I have passport strategy like this:

    ssoOptions = {
      identityMetadata: `https://login.microsoftonline.com/${this.TENANT_ID}/${this.VERSION}/.well-known/openid-configuration`,
      clientID: this.TENANT_ID,
      clientSecret: this.TENANT_SECRET,
      redirectUrl: this.TENANT_REDIRECT_URL,
      validateIssuer: true,
      isB2C: true,
      loggingLevel: 'warn',
      responseMode: 'form_post',
      responseType: 'code id_token',
      passReqToCallback: true,
      scope: ['openid', 'profile', 'email']
    }

    passport.use('oidc-strategy', new OIDCStrategy(ssoOptions, (req: any, iss: any, profile: any, accessToken: any, refreshToken: any, done: any) => {
      try {
      const userProfile = {
        oid: profile.oid,
        displayName: profile.displayName,
        email: profile._json.preferred_username,
        accessToken,
        refreshToken
      }
      return done(null, userProfile)
    } catch (error) {
      console.error('ERROR', error);
      return done (error);
    }
    }))
  }

And I have this route in my route.ts: but it gives me 401: Unauthorized

    api.get('/ssoSignUp/authenticate', passport.authenticate('oidc-strategy', { session: false }), (req, res) => {
        res.json(req.user);
      });

And in my Azure AD B2C App Manifest, I have this:

    "signInAudience": "AzureADandPersonalMicrosoftAccount",
  1. When testing the OAuth2 process in Postman, I see the Microsoft SSO Screen and when I enter my creds it says:
AADSTS50020: User account 'xyz@abc.com' from identity provider 'live.com' does not exist in tenant 'AppName' and cannot access the application '123123'(AppName) in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account
  1. I also want to see both SignIn and SignUp in the SSO screen, right now I only see SignIn and get that above error.

My Postman options look like this: Auth URL

https://login.microsoftonline.com/AppName.onmicrosoft.com/oauth2/v2.0/authorize

Access Token URL

https://login.microsoftonline.com/AppName.onmicrosoft.com/oauth2/v2.0/token

Callback URL

https://localhost:3000/

ClientID: someID ClientSecret: someSecret scope: openid profile email

After some tinkering, I can now get the access_token from Postman: My Auth URL is now this:

https://appName.b2clogin.com/appName.onmicrosoft.com/B2C_policy_name/oauth2/v2.0/authorize

But, I don't know what to do next with this. Basically, I want to create the user using graphAPI if it does not exist and update the azure id etc if it exists.

For my React App (just to test), these are my msalConfigs:

export const msalConfig = {
    auth: {
        clientId: '<clientID>',
        authority: `https://<tentantName>.b2clogin.com/<tentantName>.onmicrosoft.com/<policyName>/v2.0/`,
        redirectUri: 'http://localhost:3000',
        knownAuthorities: ['<tentantName>.b2clogin.com'],
    },
};

export const loginRequest = {
    scopes: ['openid', 'profile', 'User.Read'],
};


Solution

  • The error you are facing is because you are passing invalid Auth URL and Access Token URL.

    To resolve the error, you need to pass valid Auth URL and Access Token URL like below:

    Auth URL : https://infrab2c.b2clogin.com/infrab2c.onmicrosoft.com/<policy-name>/oauth2/v2.0/authorize

    Access Token URL : https://infrab2c.b2clogin.com/infrab2c.onmicrosoft.com/<policy-name>/oauth2/v2.0/token

    Created an Azure AD B2C application:

    enter image description here

    Generate the token:

    Auth URL : https://TenantName.b2clogin.com/TenantName.onmicrosoft.com/B2C_1_testruk/oauth2/v2.0/authorize
    
    Token URL: https://TenantName.b2clogin.com/TenantName.onmicrosoft.com/B2C_1_testruk/oauth2/v2.0/token
    
    Callback URL: Redirect URL
    
    Client ID: xxx
    
    Client Secret: xxx
    
    Scope: openid profile email
    

    enter image description here

    enter image description here

    Note that: Only the ID token will be generated, to generate access token in Azure AD B2C you need to pass scope which is meant for the application.

    Refer this SO Thread: Scope User.Read.All not works for azure b2c for more in detail for calling Microsoft Graph API