

Getting started with AAD integration in JavaScript
source link: https://blog.joouis.com/2021/getting-started-with-aad-integration-in-javascript/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Relationship between OAuth2.0, AAD and MSAL
Definitions
OAuth 2.0
OAuth 2.0 is the industry-standard protocol for authorization. OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications, desktop applications, mobile phones, and living room devices.
Azure Authentication Directory
One of OAuth 2.0 and OpenID Connect standard-compliant authentication service enabling developers to authenticate work or school accounts. It’s the implementation which supports OAuth 2.0. It’s the component of Microsoft Identity platform.
Microsoft Authentication Libraries
Open source libraries for several clients to authenticate users using AAD, Microsoft personal accounts (MSA), and social identity providers like Facebook, Google, LinkedIn, Microsoft accounts, etc.
Usage scenario
Workflow and implementation
Authentication flow
Two APIs
Only two APIs requested from client-side, very simple. Notice that /oauth2/v2.0/authorize
is document
type.
Redirect URI setup
For CORS and redirect target from sign-in page usage, should configure it on both Azure Portal and codebase.
Configuration on Azure Portal
oauth.html
Usually we will set two reply URIs, one is probably the homepage as redirect target after signed in, another is used for requesting token silently. The silent token refresh loads an iframe using that empty oauth.html
file, and that same oauth.html
file needs to receive the response back, so the acquire token silent flow provides the /oauth.html
endpoint as the redirect URI. This is different from the user-facing flow because there is no iframe that the middleware loads into the page, redirecting back to oauth.html
will not hook into React or MSAL and auth would halt – it must redirect back to your react app in the user-facing flow.
Code configuration
const config = {
auth: {
// The application ID of your AAD application
clientId: "11111111-1111-1111-111111111111",
// The authority URL for your application
authority: "https://login.microsoftonline.com/common",
// Defaults to application start page
redirectUri: "https://localhost:3000",
postLogoutRedirectUri: "https://localhost:3000/logout"
}
}
const loginRequest = {
scopes: [`${resourceEndpoint}/.default`]
}
Authority
The authority is a URL that indicates a directory that MSAL can request tokens from, for more details check the MSAL Application configuration options.
Scopes and permissions
Applications that integrate with the Microsoft identity platform follow an authorization model that gives users and administrators control over how data can be accessed. /.default
represents OpenID Connect scopes, for more details check the Permissions and consent in the Microsoft identity platform.
Sign-in with redirect
It’s no need to redirect to sign-in page every time if auth is not expired, just go ahead. You can also sign-in with a pop-up window.
let username = "";
const msalInstance = new PublicClientApplication(config);
function handleResponse(response) {
//handle redirect response
// In case multiple accounts exist, you can select
const currentAccounts = msalInstance.getAllAccounts();
if (currentAccounts === null) {
// No accounts detected, need to login
msalInstance.loginRedirect(loginRequest);
} else if (currentAccounts.length > 1) {
// Add choose account code here
} else if (currentAccounts.length === 1) {
username = currentAccounts[0].username;
}
}
msalInstance.handleRedirectPromise().then(handleResponse);
Authorization code
After signed in successfully, page will redirect to the redirect URI we set before with the authorization code. MSAL.js library will handle it automatically, we can observe the code on the navigation bar.
Then the library will parse the authorization code and send the request to get token back directly, all logics encapsulated. Here is the structure of the decoded code.
Acquire a token with a redirect
The pattern for acquiring tokens for APIs with MSAL.js is to first attempt a silent token request by using the acquireTokenSilent
method. When this method is called, the library first checks the cache in browser storage to see if a valid token exists and returns it. When no valid token is in the cache, it sends a silent token request to AAD from a hidden iframe.
The silent token requests to AAD might fail for reasons like an expired Azure AD session or a password change. In that case, we need to redirect or using a pop-up window to acquire tokens.
const accessTokenRequest: AuthenticationParameters = {
scopes: [`${resourceEndpoint}/.default`],
authority: this.authority,
redirectUri: "https://localhost:3000/oauth.html",
account: this.account
}
msalInstance.acquireTokenSilent(accessTokenRequest).then(function(accessTokenResponse) {
// Acquire token silent success
// Call API with token
let accessToken = accessTokenResponse.accessToken;
}).catch(function (error) {
//Acquire token silent failure, and send an interactive request
console.log(error);
if (error.errorMessage.indexOf("interaction_required") !== -1) {
msalInstance.acquireTokenRedirect(accessTokenRequest);
}
});
Why use redirect way?
If users have browser constraints or policies where pop-ups windows are disabled, you can use the redirect method. Use the redirect method with the Internet Explorer browser, because there are known issues with pop-up windows on Internet Explorer.
Choice of MSAL.js
You will find so many packages when you visit MSAL.js repository, APIs used above should be compatible across the packages, then question comes: how to make a choice?
Besides node package using in the server-side, I recommend msal-browser
(Microsoft Authentication Library for JavaScript v2.x) or other UI framework wrappers based on it, for its implementation of OAuth 2.0 Authorization Code Flow with PCKE as well as it’s OpenID-compliant.
These packages are just official engineering implementations, not so well-documented yet, I had to read the source code for debugging before. Anyway as long as you master the workflow of authentication, it would not be too complicated.
Frequently asked issues
Debugging and verification approach
You can’t verify your change until the production release, also the change for the production environment can’t be verified on other staging environment since they are using different hosts. So the question is how to debug or do verification?
Basically you can run a local server to host your application with adding a host record which points the production host to your local IP address like 127.0.0.1
to make it. Remember to enable HTTPS protocol for your local server.
And it’s better to verify your change on both common window and incognito window after the release.
Difference between access token, ID token, and refresh token
We observed that /oauth2/v2.0/token
return 3 tokens: access_token
, id_token
and refresh_token
.
access_token
enables clients to securely call protected web APIs, and are used by web APIs to perform authentication and authorization. For more details please check Microsoft identity platform access tokens.
id_token
should be used to validate that a user is who they claim to be and get additional useful information about them, it can be sent alongside or instead of an access token. We have not used it. For more details please check Microsoft identity platform ID tokens.
access_token
and id_token
are both JWT which consists of a header, payload, and signature portion, that’s why they look so similiar though these two strings are base64 encoded. We mainly use access token for the application, it contains more information than ID token, and we can get user info like name, E-mail from it.
Because access tokens are valid for only a short period of time, authorization servers will sometimes issue a refresh token at the same time the access token is issued. MSAL.js will exchange the refresh_token
while request token silently for a new access token when needed.
How to change token expiration time?
Please check this answer from StackOverflow.
InteractionRequiredAuthError: AADSTS50058: A silent sign-in request was sent but no user is signed in.
This error need interaction sign in, thus catch the error and call acquireTokenRedirect
method to sign in.
If the error message contains like this “The cookies used to represent the user’s session were not sent in the request to Azure AD. This could happen if the user is using Internet Explorer or Edge, and the web app sending the silent sign-in request is in different IE security zone than the Azure AD endpoint (login.microsoftonline.com).”, upgrade your MSAL.js v1.x to v2.x. Check more details here.
The frame attempting navigation of the top-level window is sandboxed, but the flag of ‘allow-top-navigation’ or ‘allow-top-navigation-by-user-activation’ is not set.
This error usually occurred while requesting token, mostly it’s caused by wrong reply URL which iframe could not load it to request token silently. So make sure your reply URL pointing to the blank static HTML resource is right. Additional, this error message is somehow confusing cause it does not tell the root cause directly, check more details here.
BrowserAuthError: pcke_not_created: The PCKE code challenge and verifier could not be generated.
Check the protocol and be sure it’s HTTPS.
References
Recommend
-
4
Introduction I was scrolling through my Facebook newsfeed the other day and I happened to notice how so much information is neatly arranged and displayed with the help of cards. Each card is different and has its own properties. Imag...
-
8
Getting Started with Python Integration to SAS® Viya® - Part 5 - Loading Server-Side Files into Memory
-
9
Use AAD Authentication for Pods running in AKS 2 days ago2021-10-25T00:00:00+02:00 by Wolfgang Ofner 16 minSince the dawn of time, authentication has been a problem for developers and securit...
-
6
Implement AAD Authentication to access Azure SQL Databases Oct 312021-11-01T00:00:00+01:00 by Wolfgang Ofner 13 minMicrosoft promotes going passwordless for a while now. Azure offers authenti...
-
14
Getting Started with Python Integration to SAS® Viya® - Part 6 - Descriptive Statistics
-
11
About Author Peter StyliadisTechnical Training Consultant Peter Styliadis is a Technical Training Consultant at SAS on the Foundations...
-
8
Home Flutter & Dart Tutorials Integration Testing in Flu...
-
9
Thorsten Duevelmeyer May 15, 2022 6 min...
-
14
Stripe Elements Integration: Getting Started Recently, I was involved with a project that required the client to collect payments from their customers. This brought up many questions on the best approach to process...
-
6
Welcome to the seventh installment in my series Getting Started with Python Integration to SAS Viya. In pr...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK