Web app that signs in users: Code configuration

This article describes how to configure code for a web app that signs in users.

Microsoft libraries supporting web apps

The following Microsoft libraries are used to protect a web app (and a web API):

Language / framework Project on
GitHub
Package Getting
started
Sign in users Access web APIs Generally available (GA) or
Public preview1
.NET MSAL.NET Microsoft.Identity.Client Library cannot request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
.NET Microsoft.IdentityModel Microsoft.IdentityModel Library cannot request ID tokens for user sign-in.2 Library cannot request access tokens for protected web APIs.2 GA
ASP.NET Core Microsoft.Identity.Web Microsoft.Identity.Web Quickstart Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Java MSAL4J msal4j Quickstart Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Spring spring-cloud-azure-starter-active-directory spring-cloud-azure-starter-active-directory Tutorial Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Node.js MSAL Node msal-node Quickstart Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Python MSAL Python msal Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. GA
Python identity identity Quickstart Library can request ID tokens for user sign-in. Library can request access tokens for protected web APIs. --

(1) Universal License Terms for Online Services apply to libraries in Public preview.

(2) The Microsoft.IdentityModel library only validates tokens - it can't request ID or access tokens.

Select the tab that corresponds to the platform you're interested in:

Code snippets in this article and the following are extracted from the Node.js web application signing users in sample in MSAL Node.

You might want to refer to this sample for full implementation details.

Configuration files

Web applications that sign in users by using the Microsoft identity platform are configured through configuration files. Those files must specify the following values:

  • The cloud instance if you want your app to run in national clouds, for example. The different options include;
    • https://login.partner.microsoftonline.cn/common for Microsoft Entra China operated by 21Vianet
  • The audience in the tenant ID. The options vary depending on whether your app is single tenant or multitenant.
    • The tenant GUID obtained from the Azure portal to sign in users in your organization. You can also use a domain name.
    • organizations to sign in users in any work or school account
    • common to sign in users with any work or school account
  • The client ID for your application, as copied from the Azure portal

You might also see references to the authority, a concatenation of the instance and tenant ID values.

Here, the configuration parameters reside in .env.dev as environment variables:

CLOUD_INSTANCE="Enter_the_Cloud_Instance_Id_Here" # cloud instance string should end with a trailing slash
TENANT_ID="Enter_the_Tenant_Info_Here"
CLIENT_ID="Enter_the_Application_Id_Here"
CLIENT_SECRET="Enter_the_Client_Secret_Here"

REDIRECT_URI="http://localhost:3000/auth/redirect"
POST_LOGOUT_REDIRECT_URI="http://localhost:3000"

GRAPH_API_ENDPOINT="Enter_the_Graph_Endpoint_Here" # graph api endpoint string should end with a trailing slash

EXPRESS_SESSION_SECRET="Enter_the_Express_Session_Secret_Here"

These parameters are used to create a configuration object in authConfig.js file, which will eventually be used to initialize MSAL Node:

/*
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License.
 */

require('dotenv').config({ path: '.env.dev' });

/**
 * Configuration object to be passed to MSAL instance on creation.
 * For a full list of MSAL Node configuration parameters, visit:
 * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/configuration.md
 */
const msalConfig = {
    auth: {
        clientId: process.env.CLIENT_ID, // 'Application (client) ID' of app registration in Azure portal - this value is a GUID
        authority: process.env.CLOUD_INSTANCE + process.env.TENANT_ID, // Full directory URL, in the form of https://login.partner.microsoftonline.cn/<tenant>
        clientSecret: process.env.CLIENT_SECRET // Client secret generated from the app registration in Azure portal
    },
    system: {
        loggerOptions: {
            loggerCallback(loglevel, message, containsPii) {
                console.log(message);
            },
            piiLoggingEnabled: false,
            logLevel: 3,
        }
    }
}

const REDIRECT_URI = process.env.REDIRECT_URI;
const POST_LOGOUT_REDIRECT_URI = process.env.POST_LOGOUT_REDIRECT_URI;
const GRAPH_ME_ENDPOINT = process.env.GRAPH_API_ENDPOINT + "v1.0/me";

module.exports = {
    msalConfig,
    REDIRECT_URI,
    POST_LOGOUT_REDIRECT_URI,
    GRAPH_ME_ENDPOINT
};

In the Azure portal, the reply URIs that you register on the Authentication page for your application need to match the redirectUri instances that the application defines (http://localhost:3000/auth/redirect).

For simplicity in this article, the client secret is stored in the configuration file. In the production app, consider using a key vault or an environment variable. An even better option is to use a certificate.

Initialization code

The initialization code differences are platform dependent. For ASP.NET Core and ASP.NET, signing in users is delegated to the OpenID Connect middleware. The ASP.NET or ASP.NET Core template generates web applications for the Azure AD v1.0 endpoint. Some configuration is required to adapt them to the Microsoft identity platform.

The Node sample uses the Express framework. MSAL is initialized in auth route handler:

var express = require('express');

const authProvider = require('../auth/AuthProvider');
const { REDIRECT_URI, POST_LOGOUT_REDIRECT_URI } = require('../authConfig');

const router = express.Router();

router.get('/signin', authProvider.login({
    scopes: [],
    redirectUri: REDIRECT_URI,
    successRedirect: '/'

Next step