Building a Simple Sign-In Page with MSAL.js for Microsoft Identities
In this post I will discuss how I used MSAL.js to build a simple sign-in experience for Microsoft Identities, and some of the things I learned along the way.
I have worked with a lot of different people to onboard to Microsoft's Identity system. Whether it be app registration, app development, or even debugging the login experience, people quickly learn that authentication and authorization isn't always as straightforward as one might expect.
It is for that reason I think it is really important to build minimal, complete, and verifiable examples of the authentication process. I previously had built a minimal authentication sample for ADAL .NET using PowerShell, and this ended up having a number of different uses.
I want to do the same for MSAL.js!
My goals:
- Create a login page
- Use only basic HTML + JavaScript
- Does not require a 'web server', just simple web hosting
- Can obtain an Access Token for a custom resource, with custom scopes
- (Stretch Goal) Allow a user to use their own App ID for getting an access token
Starting with a Minimal example
Fortunately, MSAL.js has a set of really great minimal examples which do not require a back-end web server, unlike its predecessor ADAL.js whose samples ALL require a .NET backend. (WHY???)
Although there is a minimal.html
file, I would not start there, since I do not feel that it follows the best practices of using the library. Instead, start with the index.html
which is still very raw, but includes an applicationConfig
object, functionalizes the login flow, and also has a basic UX.
One of the important things I came to realize was the importance of creating a global variable for the MSAL.UserAgentApplication
object. It seems to do a lot of different things like listen for the callback from the popup window that gets created, and captures the returned ID and access token to be ingested by the acquireToken
functions. I had mistakenly wrapped this variable into my login function, and the results were... weird.
When using the popup experience, the redirection happened WITHIN the popup itself rather than the main page where the sign-in experience was initiated.
This was a really awful experience, which then made me go down the path of switching loginPopup
to loginRedirect
so that the user would stay on the same page the whole time. However, this then caused issues where the ID token would just end up in the URL as a fragment (#
) and the callback function which turned an ID token into an access token would not work anymore!
When I first was building this page, I actually ignored these problems, since I was working on a Hackathon, and I just needed to keep building. However, I can say that all of this really was caused simply by NOT having the UserAgentApplication
object in the global context.
SO DON'T DO THAT!