Add Azure MSAL/Active Directory SAML to existing web app NodeJS backend

151 Views Asked by At

I have a NodeJS app that uses conventional username/password with a hashed password in the database. I have been asked to implement single sign-on using Microsoft Azure Active Directory/Entra ID (called AD below).

To get started, I implemented an OpenID flow by adding a login page (based on MS sample code using 'npm i @azure/msal-node') that pops up a window, does the auth against AD and redirects to my app with a token in a cookie. The user clicks Enter to send the token to the backend which uses it to get the identity from AD.

The actual use case I need is SAML. I cannot make it work. Having burned several days, I am deeply traumatized.

After failing to create a local login page with popup as I did with OpenID, I turned to the facility on the Azure SAML configuration page to "Test single sign-on with [MY] SAML APP", This presents a button that pops up a sign in page and redirects to my app. There, I capture the "samlResponse" and present it to a function that is supposed to use it to find out who logged in.

I have searched for sample code with very little result. Eventually, I thought to see if Azure had API documentation. There is none but that lead me to a trove of examples, none of which mention SAML. One did, however, mention certificates, ie, "auth-code-with-certs". No joy. It came with sample certificate and key. The certificate was expired when I upload it to Azure. No matter what I did, I got the same error as always, "secretOrPrivateKey must be an asymmetric key when using RS256".

I did other things but eventually, I got the idea of using a clientSecret instead of a certificate. This told me that I need a redirectUri. WTAF? (For the OpenID version, I use 'msal-browser.js' in the login page. It makes sense for that to ask for a redirect.)

Though I have read a million things on this journey, I now wonder if I understand anything about it.

Here is the code I adapted from the example that I am using. It gets the bad key error. If I replace the clientCertificate with clientSecret, I get the redirect error:

const getUserInfo = (samlResponse, callback) => {
    const auth = {
        clientId: '1c3b4392-c123-4f88-b1ba-b32255b18141',
        authority:
            'https://login.microsoftonline.com/bba67e09-06e0-4d07-9123-acdb7a262a91',
        clientCertificate: {
            thumbprint: '2F4848A44EEEC7294E9B75743CE62A40826D1193', // can be obtained when uploading certificate to Azure AD
            privateKey: `-----BEGIN OPENSSH PRIVATE KEY----- [REMOVED FOR READABILITY] -----END OPENSSH PRIVATE KEY-----`
        }
    };
    const cca = new msal.ConfidentialClientApplication({
        auth
    });
    const tokenRequest = {
        code: ssoToken,
        scopes: ['https://graph.microsoft.com/User.Read']
    };

    cca
        .acquireTokenByCode(samlResponse)
        .then(response => {
            const { username: userName, name } = response;
            callback('', { username: userName, name });
        })
        .catch(error => {
            callback(error);
        });
};

(It came from HERE.)

So, here is what I am asking:

  1. My flow is get samlResponse, use backend code to send it to AD to get user info. Is this essentially correct?

  2. If not, what should the flow be?

  3. Does anyone know where I can see Javascript to accomplish this? The lack of code examples is amazing.

I really need some help so, thank you, please.

0

There are 0 best solutions below