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",
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
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'],
};
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:
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
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