node.jsrestazure-ad-msalmsal

Login user with email password via REST API with Azure AD and MSAL


I have a scenario where I have a react native app and a nodejs server. I need to authenticate users with Azure AD. I first thought of social auth using auth providers like Clerk, Appwrite, Supabase, Firebase, etc, but decided to instead do this: user enters their email and password and it will be sent to the backend nodejs api. This API will then use MSAL (or something better if we have it), and authenticate that user against the university's Azure AD and then send a token back to the RN app. When RN app hits the /getStudentData endpoint, it will validate the token and fetch the student's data from the database.

I couldn't find the exact docs or tutorial I was looking for. Does anyone have any experience with something like this? I need to protect my API routes with MSAL but also have the ability to signin user with email and pwd. Is this a good architecture? Any recommendations for me? Thanks.


Solution

  • Note that: If you want to use email and password to login or authenticate the user, you can make use of acquireTokenByUsernamePassword method.

    Create an Azure AD application and grant API permissions based on your requirement:

    enter image description here

    Generated access token using below parameters via Postman:

    https://login.microsoftonline.com/TenantID/oauth2/v2.0/token
    
    grant_type:password
    scope:api://xxx/test.read
    username:user@xxx.onmicrosoft.com
    password:***
    client_id:ClientID
    

    enter image description here

    To do the same in msal-node, use the below code:

    const msal = require("@azure/msal-node");
    
    const msalConfig = {
        auth: {
            clientId: "ClientID",
            authority: "Authority",
        }
    };
    
    const pca = new msal.PublicClientApplication(msalConfig);
    const usernamePasswordRequest = {
        scopes: ["scope"],
        username: "username", 
        password: "***",
    };
    
    pca.acquireTokenByUsernamePassword(usernamePasswordRequest).then((response) => {
        console.log("acquired token by password grant");
    }).catch((error) => {
        console.log(error);
    });
    

    Otherwise make use of acquireTokenByCode() by referring this MsDoc.