MSAL: Getting the Microsoft Samples Working — Why DevOps is just so good

Sebastian Rogers
6 min readMar 9, 2022

--

TL;DR Things are never as simple as they seem and its hard to follow written instructions, especially if you don’t start at the beginning, DevOps resolves this.

Another true story and one that again illustrates how bad humans are at orchestration, in this case me.

It started simply enough — upgrade an Azure Function from ADAL to MSAL.

No problems I thought so I looked for and found a suitable sample from Microsoft. I’ll just get this working so I understand it before I integrate it into the function.

Step 1: Create a GitHub Codespace

I don’t use an actual machine for development, especially not for investigations, instead I spin up a GitHub Codespace and use that. It keeps everything clean and tidy and it isolates any package installations from any other development.

This is only an option if you have a reasonable internet connection, don’t try using it from a train or if you’re relying on a regular connection in the UK, but if you can stream Netflix then you have enough oomph.

Outcome: It worked I have a Codespace with the code installed in it

Step 2: Find the sample I’m interested in

I scanned the README.md file and it referred me to a samples folder

In that folder was an msal-node-samples folder

In that folder was a README.md file and that told me there was a client-credentials sample in a client-credentials folder, perfect an Azure Function is a daemon app, so this will be good for me and I can test it from a console.

In the client-credentials folder was a readme.md and it has a Setup section

Outcome: Success, I think I have found how to get the sample running.

Step 3: Build the sample

Looks very simple so I follow the instructions.

cd samples/msal-node-samples/client-credentials/
npm install

I register my Azure Active Directory App Registration.

I create a client secret, I’ll use a certificate in the production system but for proof of concept a secret is fine.

I update the AAD.json file, this takes a while to find but once I notice there is a config folder its quick enough. Bit worried that this file could be checked into GitHub if I’m not careful but its a PoC so I live with it.

Outcome: Success, I have configured my app.

Step 4: Run the sample

Again we have instructions: microsoft-authentication-library-for-js/samples/msal-node-samples/client-credentials at dev · AzureAD/microsoft-authentication-library-for-js (github.com)

Very easy I’ll just

npm start

Outcome: Failure

> msal-node-client-credentials@1.0.0 start /workspaces/microsoft-authentication-library-for-js/samples/msal-node-samples/client-credentials
> node index.js
internal/modules/cjs/loader.js:329
throw err;
^
Error: Cannot find module '/workspaces/microsoft-authentication-library-for-js/samples/msal-node-samples/client-credentials/node_modules/@azure/msal-node/dist/index.js'. Please verify that the package.json has a valid "main" entry
at tryPackage (internal/modules/cjs/loader.js:321:19)
at Function.Module._findPath (internal/modules/cjs/loader.js:534:18)
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:888:27)
at Function.Module._load (internal/modules/cjs/loader.js:746:27)
at Module.require (internal/modules/cjs/loader.js:974:19)
at require (internal/modules/cjs/helpers.js:93:18)
at Object.<anonymous> (/workspaces/microsoft-authentication-library-for-js/samples/msal-node-samples/client-credentials/index.js:6:12)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32) {
code: 'MODULE_NOT_FOUND',
path: '/workspaces/microsoft-authentication-library-for-js/samples/msal-node-samples/client-credentials/node_modules/@azure/msal-node/package.json',
requestPath: '@azure/msal-node'
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! msal-node-client-credentials@1.0.0 start: `node index.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the msal-node-client-credentials@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/codespace/.npm/_logs/2022-03-09T12_18_36_437Z-debug.log

Step 5: Make a cup of coffee

When something happens unexpectedly a break is good.

Outcome: Success, I only read the third readme file, there were two others I must have missed something.

Step 6: Install the pre-requisites

Yes in the second readme there were some pre-requisites I hadn’t spotted. https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/samples/msal-node-samples#pre-requisites

So this is the project for MSAL itself and within the project it references the compiled project and not the npm registry. That makes sense this allows us to debug and play with MSAL.

Simple all I have to do is compile the MSAL code and we’ll be ready to go, well done coffee.

There’s a guide for this at https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/README.md#build-and-test. So I follow it

cd lib
cd msal-common
npm run build
cd ..
cd msal-node
npm run build

Outcome: Failure, on the last command I get:

> @azure/msal-node@1.7.0 build /workspaces/microsoft-authentication-library-for-js/lib/msal-node
> tsdx build --tsconfig ./tsconfig.build.json
sh: 1: tsdx: not found
npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! @azure/msal-node@1.7.0 build: `tsdx build --tsconfig ./tsconfig.build.json`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the @azure/msal-node@1.7.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/codespace/.npm/_logs/2022-03-09T14_06_28_690Z-debug.log

Maybe the coffee wasn’t strong enough.

Step 7: Install ALL the pre-requisites

I read the guide again: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/README.md#build-and-test.

This time I pay attention to:

If you don’t have lerna installed, run npm install -g lerna

Why didn’t I do this? I don’t know but I think I thought that GitHub Codespaces had it already.

So I install it, globally. I never like installing npm packages globally in case there is a conflict with another project but as we are in a Codespace just like when using a pipeline nothing else shares this environment so global is fine.

Outcome: Failure

sh: 1: tsdx: not found
npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! @azure/msal-node@1.7.0 build: `tsdx build --tsconfig ./tsconfig.build.json`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the @azure/msal-node@1.7.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/codespace/.npm/_logs/2022-03-09T14_24_35_852Z-debug.log

Step 8: Debug

The line that failed is apparently:

tsdx build --tsconfig ./tsconfig.build.json

So is tsdx installed?

I search the project for references to it and its in the msal-node package.json file: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/package.json

Okay so the instructions didn’t tell me to do an npm install. I’ll do that.

cd lib/msal-node/
npm install
npm run build

Outcome: Success, there are dist folders for both msal-common msal-node.

Step 9: Run the sample again

Back to the instructions: microsoft-authentication-library-for-js/samples/msal-node-samples/client-credentials at dev · AzureAD/microsoft-authentication-library-for-js (github.com)

Very easy I’ll just

cd samples/msal-node-samples/client-credentials/
npm start

Outcome: Failure, as there is no error but no response.

> msal-node-client-credentials@1.0.0 start /workspaces/microsoft-authentication-library-for-js/samples/msal-node-samples/client-credentials
> node index.js

Step 10: Debug the sample

Its odd I got no response from the console app. However I am in a Codespace so I can access the JavaScript Debug Terminal and debug the node console app.

I set a breakpoint then just run the console app in the JavaScript Debug Terminal allowing me to step through the sample, and if I need to right into the MSAL code itself.

This let me find some interesting things:

  1. logging is off by default: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/samples/msal-node-samples/client-credentials/index.js#L65
  2. console logging is implemented but commented out: https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/samples/msal-node-samples/client-credentials/index.js#L43

And most interestingly it works.

Outcome: Success, and I’m very impressed by how easy it is to do the debugging as well.

Step 11: Clean up

This would make my parents proud. Now I have done the work its time to clean up and again Codespaces to the rescue.

All I need to do is document what I’ve done, see this blog entry, and delete the Codespace and its done, and I’m not paying for the Codespace any more.

The ease of spinning up and deleting Codespaces really helps.

Outcome: Success I’ve written a blog and I’ve deleted the codespace.

Step 12: Reflect

Just following this simple set of instructions threw me.

  • They were split over three files, and I skimmed the first one in the chain and missed out needing to build the MSAL libraries and install lerna.
  • They were incorrect, the npm install step was missing.

I am spoilt using DevOps as the pipelines are comprehensive and orchestrated which means the following happen on the first run and not thereafter.

TL;DR Things are never as simple as they seem and its hard to follow written instructions, especially if you don’t start at the beginning, DevOps resolves this.

--

--

Sebastian Rogers

Technical Director for Simple Innovations Ltd. First paid for code in 1980, but still has all his own hair.