master
nannal 3 years ago
commit 6bb353de89

@ -0,0 +1,9 @@
# Microsoft Open Source Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
Resources:
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns

@ -0,0 +1,33 @@
<!--
IF SUFFICIENT INFORMATION IS NOT PROVIDED VIA THE FOLLOWING TEMPLATE THE ISSUE MIGHT BE CLOSED WITHOUT FURTHER CONSIDERATION OR INVESTIGATION
-->
> Please provide us with the following information:
> ---------------------------------------------------------------
### This issue is for a: (mark with an `x`)
```
- [ ] bug report -> please search issues before submitting
- [ ] feature request
- [ ] documentation issue or request
- [ ] regression (a behavior that used to work and stopped in a new release)
```
### Minimal steps to reproduce
>
### Any log messages given by the failure
>
### Expected/desired behavior
>
### OS and Version?
> Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)
### Versions
>
### Mention any other details that might be useful
> ---------------------------------------------------------------
> Thanks! We'll be in touch soon.

@ -0,0 +1,45 @@
## Purpose
<!-- Describe the intention of the changes being proposed. What problem does it solve or functionality does it add? -->
* ...
## Does this introduce a breaking change?
<!-- Mark one with an "x". -->
```
[ ] Yes
[ ] No
```
## Pull Request Type
What kind of change does this Pull Request introduce?
<!-- Please check the one that applies to this PR using "x". -->
```
[ ] Bugfix
[ ] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Documentation content changes
[ ] Other... Please describe:
```
## How to Test
* Get the code
```
git clone [repo-address]
cd [repo-name]
git checkout [branch-name]
npm install
```
* Test the code
<!-- Add steps to run the tests suite and/or manually test -->
```
```
## What to Check
Verify that the following are valid
* ...
## Other Information
<!-- Add any other helpful information that may be needed here. -->

121
.gitignore vendored

@ -0,0 +1,121 @@
# ---> Node
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
config.js

@ -0,0 +1,186 @@
# Registering the sample apps with the Microsoft identity platform and updating the configuration files using PowerShell
## Overview
### Quick summary
1. On Windows run PowerShell as **Administrator** and navigate to the root of the cloned directory
1. In PowerShell run:
```PowerShell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
```
1. Run the script to create your Azure AD application and configure the code of the sample application accordingly. (Other ways of running the scripts are described below)
```PowerShell
cd .\AppCreationScripts\
.\Configure.ps1
```
1. Open the Visual Studio solution and click start
### More details
The following paragraphs:
- [Registering the sample apps with the Microsoft identity platform and updating the configuration files using PowerShell](#Registering-the-sample-apps-with-the-Microsoft-identity-platform-and-updating-the-configuration-files-using-PowerShell)
- [Overview](#Overview)
- [Quick summary](#Quick-summary)
- [More details](#More-details)
- [Goal of the provided scripts](#Goal-of-the-provided-scripts)
- [Presentation of the scripts](#Presentation-of-the-scripts)
- [Usage pattern for tests and DevOps scenarios](#Usage-pattern-for-tests-and-DevOps-scenarios)
- [How to use the app creation scripts?](#How-to-use-the-app-creation-scripts)
- [Pre-requisites](#Pre-requisites)
- [Run the script and start running](#Run-the-script-and-start-running)
- [Four ways to run the script](#Four-ways-to-run-the-script)
- [Option 1 (interactive)](#Option-1-interactive)
- [Option 2 (non-interactive)](#Option-2-non-interactive)
- [Option 3 (Interactive, but create apps in a specified tenant)](#Option-3-Interactive-but-create-apps-in-a-specified-tenant)
- [Option 4 (non-interactive, and create apps in a specified tenant)](#Option-4-non-interactive-and-create-apps-in-a-specified-tenant)
- [Running the script on Azure Sovereign clouds](#Running-the-script-on-Azure-Sovereign-clouds)
## Goal of the provided scripts
### Presentation of the scripts
This sample comes with two PowerShell scripts, which automate the creation of the Azure Active Directory applications, and the configuration of the code for this sample. Once you run them, you will only need to build the solution and you are good to test.
These scripts are:
- `Configure.ps1` which:
- creates Azure AD applications and their related objects (permissions, dependencies, secrets),
- changes the configuration files in the C# and JavaScript projects.
- creates a summary file named `createdApps.html` in the folder from which you ran the script, and containing, for each Azure AD application it created:
- the identifier of the application
- the AppId of the application
- the url of its registration in the [Azure portal](https://portal.azure.com).
- `Cleanup.ps1` which cleans-up the Azure AD objects created by `Configure.ps1`. Note that this script does not revert the changes done in the configuration files, though. You will need to undo the change from source control (from Visual Studio, or from the command line using, for instance, git reset).
### Usage pattern for tests and DevOps scenarios
The `Configure.ps1` will stop if it tries to create an Azure AD application which already exists in the tenant. For this, if you are using the script to try/test the sample, or in DevOps scenarios, you might want to run `Cleanup.ps1` just before `Configure.ps1`. This is what is shown in the steps below.
## How to use the app creation scripts?
### Pre-requisites
1. Open PowerShell (On Windows, press `Windows-R` and type `PowerShell` in the search window)
1. Navigate to the root directory of the project.
1. Until you change it, the default [Execution Policy](https:/go.microsoft.com/fwlink/?LinkID=135170) for scripts is usually `Restricted`. In order to run the PowerShell script you need to set the Execution Policy to `RemoteSigned`. You can set this just for the current PowerShell process by running the command:
```PowerShell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
```
### (Optionally) install AzureAD PowerShell modules
The scripts install the required PowerShell module (AzureAD) for the current user if needed. However, if you want to install if for all users on the machine, you can follow the following steps:
1. If you have never done it already, in the PowerShell window, install the AzureAD PowerShell modules. For this:
1. Open PowerShell as admin (On Windows, Search Powershell in the search bar, right click on it and select Run as administrator).
2. Type:
```PowerShell
Install-Module AzureAD
```
or if you cannot be administrator on your machine, run:
```PowerShell
Install-Module AzureAD -Scope CurrentUser
```
### Run the script and start running
1. Go to the `AppCreationScripts` sub-folder. From the folder where you cloned the repo,
```PowerShell
cd AppCreationScripts
```
1. Run the scripts. See below for the [four options](#four-ways-to-run-the-script) to do that.
1. Open the Visual Studio solution, and in the solution's context menu, choose **Set Startup Projects**.
1. select **Start** for the projects
You're done. this just works!
### Four ways to run the script
We advise four ways of running the script:
- Interactive: you will be prompted for credentials, and the scripts decide in which tenant to create the objects,
- non-interactive: you will provide credentials, and the scripts decide in which tenant to create the objects,
- Interactive in specific tenant: you will provide the tenant in which you want to create the objects and then you will be prompted for credentials, and the scripts will create the objects,
- non-interactive in specific tenant: you will provide tenant in which you want to create the objects and credentials, and the scripts will create the objects.
Here are the details on how to do this.
#### Option 1 (interactive)
- Just run ``. .\Configure.ps1``, and you will be prompted to sign-in (email address, password, and if needed MFA).
- The script will be run as the signed-in user and will use the tenant in which the user is defined.
Note that the script will choose the tenant in which to create the applications, based on the user. Also to run the `Cleanup.ps1` script, you will need to re-sign-in.
#### Option 2 (non-interactive)
When you know the identity and credentials of the user in the name of whom you want to create the applications, you can use the non-interactive approach. It's more adapted to DevOps. Here is an example of script you'd want to run in a PowerShell Window
```PowerShell
$secpasswd = ConvertTo-SecureString "[Password here]" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("[login@tenantName here]", $secpasswd)
. .\Cleanup.ps1 -Credential $mycreds
. .\Configure.ps1 -Credential $mycreds
```
Of course, in real life, you might already get the password as a `SecureString`. You might also want to get the password from KeyVault.
#### Option 3 (Interactive, but create apps in a specified tenant)
if you want to create the apps in a particular tenant, you can use the following option:
- open the [Azure portal](https://portal.azure.com)
- Select the Azure Active directory you are interested in (in the combo-box below your name on the top right of the browser window)
- Find the "Active Directory" object in this tenant
- Go to **Properties** and copy the content of the **Directory Id** property
- Then use the full syntax to run the scripts:
```PowerShell
$tenantId = "yourTenantIdGuid"
. .\Cleanup.ps1 -TenantId $tenantId
. .\Configure.ps1 -TenantId $tenantId
```
#### Option 4 (non-interactive, and create apps in a specified tenant)
This option combines option 2 and option 3: it creates the application in a specific tenant. See option 3 for the way to get the tenant Id. Then run:
```PowerShell
$secpasswd = ConvertTo-SecureString "[Password here]" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("[login@tenantName here]", $secpasswd)
$tenantId = "yourTenantIdGuid"
. .\Cleanup.ps1 -Credential $mycreds -TenantId $tenantId
. .\Configure.ps1 -Credential $mycreds -TenantId $tenantId
```
### Running the script on Azure Sovereign clouds
All the four options listed above, can be used on any Azure Sovereign clouds. By default, the script targets `AzureCloud`, but it can be changed using the parameter `-AzureEnvironmentName`.
The acceptable values for this parameter are:
- AzureCloud
- AzureChinaCloud
- AzureUSGovernment
- AzureGermanyCloud
Example:
```PowerShell
. .\Cleanup.ps1 -AzureEnvironmentName "AzureGermanyCloud"
. .\Configure.ps1 -AzureEnvironmentName "AzureGermanyCloud"
```

@ -0,0 +1,80 @@
[CmdletBinding()]
param(
[PSCredential] $Credential,
[Parameter(Mandatory=$False, HelpMessage='Tenant ID (This is a GUID which represents the "Directory ID" of the AzureAD tenant into which you want to create the apps')]
[string] $tenantId,
[Parameter(Mandatory=$False, HelpMessage='Azure environment to use while running the script (it defaults to AzureCloud)')]
[string] $azureEnvironmentName
)
#Requires -Modules AzureAD -RunAsAdministrator
if ($null -eq (Get-Module -ListAvailable -Name "AzureAD")) {
Install-Module "AzureAD" -Scope CurrentUser
}
Import-Module AzureAD
$ErrorActionPreference = "Stop"
Function Cleanup
{
if (!$azureEnvironmentName)
{
$azureEnvironmentName = "AzureCloud"
}
<#
.Description
This function removes the Azure AD applications for the sample. These applications were created by the Configure.ps1 script
#>
# $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant
# into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD.
# Login to Azure PowerShell (interactive if credentials are not already provided:
# you'll need to sign-in with creds enabling your to create apps in the tenant)
if (!$Credential -and $TenantId)
{
$creds = Connect-AzureAD -TenantId $tenantId -AzureEnvironmentName $azureEnvironmentName
}
else
{
if (!$TenantId)
{
$creds = Connect-AzureAD -Credential $Credential -AzureEnvironmentName $azureEnvironmentName
}
else
{
$creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential -AzureEnvironmentName $azureEnvironmentName
}
}
if (!$tenantId)
{
$tenantId = $creds.Tenant.Id
}
$tenant = Get-AzureADTenantDetail
$tenantName = ($tenant.VerifiedDomains | Where-Object { $_._Default -eq $True }).Name
# Removes the applications
Write-Host "Cleaning-up applications from tenant '$tenantName'"
Write-Host "Removing 'webApp' (ms-identity-node) if needed"
Get-AzureADApplication -Filter "DisplayName eq 'ms-identity-node'" | ForEach-Object {Remove-AzureADApplication -ObjectId $_.ObjectId }
$apps = Get-AzureADApplication -Filter "DisplayName eq 'ms-identity-node'"
if ($apps)
{
Remove-AzureADApplication -ObjectId $apps.ObjectId
}
foreach ($app in $apps)
{
Remove-AzureADApplication -ObjectId $app.ObjectId
Write-Host "Removed ms-identity-node.."
}
# also remove service principals of this app
Get-AzureADServicePrincipal -filter "DisplayName eq 'ms-identity-node'" | ForEach-Object {Remove-AzureADServicePrincipal -ObjectId $_.Id -Confirm:$false}
}
Cleanup -Credential $Credential -tenantId $TenantId

@ -0,0 +1,187 @@
[CmdletBinding()]
param(
[PSCredential] $Credential,
[Parameter(Mandatory=$False, HelpMessage='Tenant ID (This is a GUID which represents the "Directory ID" of the AzureAD tenant into which you want to create the apps')]
[string] $tenantId,
[Parameter(Mandatory=$False, HelpMessage='Azure environment to use while running the script (it defaults to AzureCloud)')]
[string] $azureEnvironmentName
)
#Requires -Modules AzureAD -RunAsAdministrator
<#
This script creates the Azure AD applications needed for this sample and updates the configuration files
for the visual Studio projects from the data in the Azure AD applications.
Before running this script you need to install the AzureAD cmdlets as an administrator.
For this:
1) Run Powershell as an administrator
2) in the PowerShell window, type: Install-Module AzureAD
There are four ways to run this script. For more information, read the AppCreationScripts.md file in the same folder as this script.
#>
# Create a password that can be used as an application key
Function ComputePassword
{
$aesManaged = New-Object "System.Security.Cryptography.AesManaged"
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
$aesManaged.BlockSize = 128
$aesManaged.KeySize = 256
$aesManaged.GenerateKey()
return [System.Convert]::ToBase64String($aesManaged.Key)
}
# Create an application key
# See https://www.sabin.io/blog/adding-an-azure-active-directory-application-and-key-using-powershell/
Function CreateAppKey([DateTime] $fromDate, [double] $durationInYears, [string]$pw)
{
$endDate = $fromDate.AddYears($durationInYears)
$keyId = (New-Guid).ToString();
$key = New-Object Microsoft.Open.AzureAD.Model.PasswordCredential
$key.StartDate = $fromDate
$key.EndDate = $endDate
$key.Value = $pw
$key.KeyId = $keyId
return $key
}
Function ReplaceInLine([string] $line, [string] $key, [string] $value)
{
$index = $line.IndexOf($key)
if ($index -ige 0)
{
$index2 = $index+$key.Length
$line = $line.Substring(0, $index) + $value + $line.Substring($index2)
}
return $line
}
Function ReplaceInTextFile([string] $configFilePath, [System.Collections.HashTable] $dictionary)
{
$lines = Get-Content $configFilePath
$index = 0
while($index -lt $lines.Length)
{
$line = $lines[$index]
foreach($key in $dictionary.Keys)
{
if ($line.Contains($key))
{
$lines[$index] = ReplaceInLine $line $key $dictionary[$key]
}
}
$index++
}
Set-Content -Path $configFilePath -Value $lines -Force
}
Set-Content -Value "<html><body><table>" -Path createdApps.html
Add-Content -Value "<thead><tr><th>Application</th><th>AppId</th><th>Url in the Azure portal</th></tr></thead><tbody>" -Path createdApps.html
$ErrorActionPreference = "Stop"
Function ConfigureApplications
{
<#.Description
This function creates the Azure AD applications for the sample in the provided Azure AD tenant and updates the
configuration files in the client and service project of the visual studio solution (App.Config and Web.Config)
so that they are consistent with the Applications parameters
#>
$commonendpoint = "common"
if (!$azureEnvironmentName)
{
$azureEnvironmentName = "AzureCloud"
}
# $tenantId is the Active Directory Tenant. This is a GUID which represents the "Directory ID" of the AzureAD tenant
# into which you want to create the apps. Look it up in the Azure portal in the "Properties" of the Azure AD.
# Login to Azure PowerShell (interactive if credentials are not already provided:
# you'll need to sign-in with creds enabling your to create apps in the tenant)
if (!$Credential -and $TenantId)
{
$creds = Connect-AzureAD -TenantId $tenantId -AzureEnvironmentName $azureEnvironmentName
}
else
{
if (!$TenantId)
{
$creds = Connect-AzureAD -Credential $Credential -AzureEnvironmentName $azureEnvironmentName
}
else
{
$creds = Connect-AzureAD -TenantId $tenantId -Credential $Credential -AzureEnvironmentName $azureEnvironmentName
}
}
if (!$tenantId)
{
$tenantId = $creds.Tenant.Id
}
$tenant = Get-AzureADTenantDetail
$tenantName = ($tenant.VerifiedDomains | Where { $_._Default -eq $True }).Name
# Get the user running the script to add the user as the app owner
$user = Get-AzureADUser -ObjectId $creds.Account.Id
# Create the webApp AAD application
Write-Host "Creating the AAD application (ms-identity-node)"
# Get a 2 years application key for the webApp Application
$pw = ComputePassword
$fromDate = [DateTime]::Now;
$key = CreateAppKey -fromDate $fromDate -durationInYears 2 -pw $pw
$webAppAppKey = $pw
# create the application
$webAppAadApplication = New-AzureADApplication -DisplayName "ms-identity-node" `
-HomePage "http://localhost:3000" `
-ReplyUrls "http://localhost:3000/redirect" `
-IdentifierUris "https://$tenantName/ms-identity-node" `
-PasswordCredentials $key `
-PublicClient $False
# create the service principal of the newly created application
$currentAppId = $webAppAadApplication.AppId
$webAppServicePrincipal = New-AzureADServicePrincipal -AppId $currentAppId -Tags {WindowsAzureActiveDirectoryIntegratedApp}
# add the user running the script as an app owner if needed
$owner = Get-AzureADApplicationOwner -ObjectId $webAppAadApplication.ObjectId
if ($owner -eq $null)
{
Add-AzureADApplicationOwner -ObjectId $webAppAadApplication.ObjectId -RefObjectId $user.ObjectId
Write-Host "'$($user.UserPrincipalName)' added as an application owner to app '$($webAppServicePrincipal.DisplayName)'"
}
Write-Host "Done creating the webApp application (ms-identity-node)"
# URL of the AAD application in the Azure portal
# Future? $webAppPortalUrl = "https://portal.azure.com/#@"+$tenantName+"/blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/Overview/appId/"+$webAppAadApplication.AppId+"/objectId/"+$webAppAadApplication.ObjectId+"/isMSAApp/"
$webAppPortalUrl = "https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/CallAnAPI/appId/"+$webAppAadApplication.AppId+"/objectId/"+$webAppAadApplication.ObjectId+"/isMSAApp/"
Add-Content -Value "<tr><td>webApp</td><td>$currentAppId</td><td><a href='$webAppPortalUrl'>ms-identity-node</a></td></tr>" -Path createdApps.html
# Update config file for 'webApp'
$configFile = $pwd.Path + "\..\index.js"
Write-Host "Updating the sample code ($configFile)"
$dictionary = @{ "Enter_the_Application_Id_Here" = $webAppAadApplication.AppId;"Enter_the_Cloud_Instance_Id_HereEnter_the_Tenant_Info_Here" = 'https://login.microsoftonline.com/common';"Enter_the_Client_Secret_Here" = $webAppAppKey };
ReplaceInTextFile -configFilePath $configFile -dictionary $dictionary
Add-Content -Value "</tbody></table></body></html>" -Path createdApps.html
}
# Pre-requisites
if ((Get-Module -ListAvailable -Name "AzureAD") -eq $null) {
Install-Module "AzureAD" -Scope CurrentUser
}
Import-Module AzureAD
# Run interactively (will ask you for the tenant ID)
ConfigureApplications -Credential $Credential -tenantId $TenantId

@ -0,0 +1,224 @@
---
page_type: sample
languages:
- csharp
- javascript
- typescript
- python
- java
products:
- node.js
- dotnet
- aspnet
- aspnet-core
- dotnet-core
- ms-graph
- azure-app-service
- azure-storage
- azure-active-directory
- azure-active-directory-b2c
name: A Node.js & Express web app authenticating users against Azure AD with MSAL Node
urlFragment: ms-identity-javascript-nodejs-tutorial
description: "This sample demonstrates a Node.js & Express web app that authenticates users against Azure AD"
azureDeploy: <ENTER_FULLY_QUALIFIED_URL_TO_AN_AZURE_RESOURCE_MANAGER>
extendedZipContent: <FILES_OR_FOLDERS_WITH_TWO_ABSOLUTE_PATHS_TO_INCLUDE_WITH_ZIP:PATH(NAME_IN_THE_REPO), TARGET(NAME_IN_THE_ZIP)>
extensions: <ENTER_CONTENT_THAT_OTHER_TEAMS_CAN_USE_TO_IDENTIFY_SAMPLES>
---
# A Node.js & Express web app authenticating users against Azure AD with MSAL Node
1. [Overview](#overview)
1. [Scenario](#scenario)
1. [Contents](#contents)
1. [Prerequisites](#prerequisites)
1. [Setup](#setup)
1. [Registration](#registration)
1. [Running the sample](#running-the-sample)
1. [Explore the sample](#explore-the-sample)
1. [About the code](#about-the-code)
1. [Deployment](#deployment)
1. [More information](#more-information)
1. [Community Help and Support](#community-help-and-support)
1. [Contributing](#contributing)
![Build badge](https://identitydivision.visualstudio.com/_apis/public/build/definitions/a7934fdd-dcde-4492-a406-7fad6ac00e17/<BuildNumber>/badge)
## Overview
This sample demonstrates a Node.js & Express web app that authenticates users against Azure AD.
## Scenario
1. The client Node.js & Express web app uses the Microsoft Authentication Library (MSAL) to obtain an ID Token from **Azure AD**.
2. The **ID Token** proves that the user has successfully authenticated against **Azure AD**.
![Overview](./ReadmeFiles/topology.png)
## Contents
> Give a high-level folder structure of the sample.
| File/folder | Description |
|-------------------|--------------------------------------------|
| `CHANGELOG.md` | List of changes to the sample. |
| `CONTRIBUTING.md` | Guidelines for contributing to the sample. |
| `LICENSE` | The license for the sample. |
## Prerequisites
- An **Azure AD** tenant. For more information see: [How to get an Azure AD tenant](https://docs.microsoft.com/azure/active-directory/develop/quickstart-create-new-tenant)
- A user account in your **Azure AD** tenant. This sample will not work with a **personal Microsoft account**. Therefore, if you signed in to the [Azure portal](https://portal.azure.com) with a personal account and have never created a user account in your directory before, you need to do that now.
## Setup
### Step 1: Clone or download this repository
From your shell or command line:
```console
git clone https://github.com/Azure-Samples/ms-identity-javascript-nodejs-tutorial.git
```
or download and extract the repository .zip file.
> :warning: To avoid path length limitations on Windows, we recommend cloning into a directory near the root of your drive.
### Register the sample application(s) with your Azure Active Directory tenant
There is one project in this sample. To register it, you can:
- follow the steps below for manually register your apps
- or use PowerShell scripts that:
- **automatically** creates the Azure AD applications and related objects (passwords, permissions, dependencies) for you.
- modify the projects' configuration files.
<details>
<summary>Expand this section if you want to use this automation:</summary>
> :warning: If you have never used **Azure AD Powershell** before, we recommend you go through the [App Creation Scripts](./AppCreationScripts/AppCreationScripts.md) once to ensure that your environment is prepared correctly for this step.
1. On Windows, run PowerShell as **Administrator** and navigate to the root of the cloned directory
1. If you have never used Azure AD Powershell before, we recommend you go through the [App Creation Scripts](./AppCreationScripts/AppCreationScripts.md) once to ensure that your environment is prepared correctly for this step.
1. In PowerShell run:
```PowerShell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
```
1. Run the script to create your Azure AD application and configure the code of the sample application accordingly.
1. In PowerShell run:
```PowerShell
cd .\AppCreationScripts\
.\Configure.ps1
```
> Other ways of running the scripts are described in [App Creation Scripts](./AppCreationScripts/AppCreationScripts.md)
> The scripts also provide a guide to automated application registration, configuration and removal which can help in your CI/CD scenarios.
</details>
### Choose the Azure AD tenant where you want to create your applications
As a first step you'll need to:
1. Sign in to the [Azure portal](https://portal.azure.com).
1. If your account is present in more than one Azure AD tenant, select your profile at the top right corner in the menu on top of the page, and then **switch directory** to change your portal session to the desired Azure AD tenant.
### Register the webApp app (ms-identity-node)
1. Navigate to the [Azure portal](https://portal.azure.com) and select the **Azure AD** service.
1. Select the **App Registrations** blade on the left, then select **New registration**.
1. In the **Register an application page** that appears, enter your application's registration information:
- In the **Name** section, enter a meaningful application name that will be displayed to users of the app, for example `ms-identity-node`.
- Under **Supported account types**, select **Accounts in this organizational directory only**.
- In the **Redirect URI (optional)** section, select **Web** in the combo-box and enter the following redirect URI: `http://localhost:3000/redirect`.
1. Select **Register** to create the application.
1. In the app's registration screen, find and note the **Application (client) ID**. You use this value in your app's configuration file(s) later in your code.
1. Select **Save** to save your changes.
1. In the app's registration screen, select the **Certificates & secrets** blade in the left to open the page where we can generate secrets and upload certificates.
1. In the **Client secrets** section, select **New client secret**:
- Type a key description (for instance `app secret`),
- Select one of the available key durations (**In 1 year**, **In 2 years**, or **Never Expires**) as per your security posture.
- The generated key value will be displayed when you select the **Add** button. Copy the generated value for use in the steps later.
- You'll need this key later in your code's configuration files. This key value will not be displayed again, and is not retrievable by any other means, so make sure to note it from the Azure portal before navigating to any other screen or blade.
#### Configure the webApp app (ms-identity-node) to use your app registration
Open the project in your IDE (like Visual Studio or Visual Studio Code) to configure the code.
> In the steps below, "ClientID" is the same as "Application ID" or "AppId".
1. Open the `index.js` file.
1. Find the key `Enter_the_Application_Id_Here` and replace the existing value with the application ID (clientId) of `ms-identity-node` app copied from the Azure portal.
1. Find the key `Enter_the_Cloud_Instance_Id_HereEnter_the_Tenant_Info_Here` and replace the existing value with 'https://login.microsoftonline.com/common'.
1. Find the key `Enter_the_Client_Secret_Here` and replace the existing value with the key you saved during the creation of `ms-identity-node` copied from the Azure portal.
## Running the sample
## Explore the sample
> Explain how to explore the sample.
> Insert a screenshot of the client application.
> :information_source: Did the sample not work for you as expected? Then please reach out to us using the [GitHub Issues](../../../issues) page.
## We'd love your feedback!
Were we successful in addressing your learning objective? Consider taking a moment to [share your experience with us](Enter_Survey_Form_Link).
## About the code
> - Describe where the code uses auth libraries, or calls the graph
> - Describe specific aspects (e.g. caching, validation etc.)
## Deployment
### Deploying web app to Azure App Services
There is one web app in this sample. To deploy it to **Azure App Services**, you'll need to:
- create an **Azure App Service**
- publish the projects to the **App Services**, and
- update its client(s) to call the website instead of the local environment.
#### Update the Azure AD app registration (ms-identity-node)
1. Navigate back to to the [Azure portal](https://portal.azure.com).
In the left-hand navigation pane, select the **Azure Active Directory** service, and then select **App registrations (Preview)**.
1. In the resulting screen, select the `ms-identity-node` application.
1. In the app's registration screen, select **Authentication** in the menu.
- In the **Redirect URIs** section, update the reply URLs to match the site URL of your Azure deployment. For example:
- `https://ms-identity-node.azurewebsites.net/redirect`
> :warning: If your app is using an *in-memory* storage, **Azure App Services** will spin down your web site if it is inactive, and any records that your app was keeping will emptied. In addition, if you increase the instance count of your website, requests will be distributed among the instances. Your app's records, therefore, will not be the same on each instance.
## More information
- [Microsoft identity platform (Azure Active Directory for developers)](https://docs.microsoft.com/azure/active-directory/develop/)
- [Overview of Microsoft Authentication Library (MSAL)](https://docs.microsoft.com/azure/active-directory/develop/msal-overview)
- [Quickstart: Register an application with the Microsoft identity platform (Preview)](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app)
- [Quickstart: Configure a client application to access web APIs (Preview)](https://docs.microsoft.com/azure/active-directory/develop/quickstart-configure-app-access-web-apis)
- [Understanding Azure AD application consent experiences](https://docs.microsoft.com/azure/active-directory/develop/application-consent-experience)
- [Understand user and admin consent](https://docs.microsoft.com/azure/active-directory/develop/howto-convert-app-to-be-multi-tenant#understand-user-and-admin-consent)
- [Application and service principal objects in Azure Active Directory](https://docs.microsoft.com/azure/active-directory/develop/app-objects-and-service-principals)
- [National Clouds](https://docs.microsoft.com/azure/active-directory/develop/authentication-national-cloud#app-registration-endpoints)
- [MSAL code samples](https://docs.microsoft.com/azure/active-directory/develop/sample-v2-code)
For more information about how OAuth 2.0 protocols work in this scenario and other scenarios, see [Authentication Scenarios for Azure AD](https://docs.microsoft.com/azure/active-directory/develop/authentication-flows-app-scenarios).
## Community Help and Support
Use [Stack Overflow](http://stackoverflow.com/questions/tagged/msal) to get support from the community.
Ask your questions on Stack Overflow first and browse existing issues to see if someone has asked your question before.
Make sure that your questions or comments are tagged with [`azure-active-directory` `azure-ad-b2c` `ms-identity` `adal` `msal`].
If you find a bug in the sample, raise the issue on [GitHub Issues](../../../issues).
To provide feedback on or suggest features for Azure Active Directory, visit [User Voice page](https://feedback.azure.com/forums/169401-azure-active-directory).
## Contributing
If you'd like to contribute to this sample, see [CONTRIBUTING.MD](/CONTRIBUTING.md).
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information, see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

@ -0,0 +1,33 @@
{
"Sample": {
"Title": "A Node.js & Express web app authenticating users against Azure AD with MSAL Node",
"Level": 100,
"Client": "Node.js & Express web app"
},
"AppRegistrations": [
{
"x-ms-id": "webApp",
"x-ms-name": "ms-identity-node",
"x-ms-version": "2.0",
"replyUrlsWithType": [
{
"url": "http://localhost:3000/redirect",
"type": "Web"
}
],
"oauth2AllowImplicitFlow": false,
"oauth2AllowIdTokenImplicitFlow": false,
"codeConfigurations": [
{
"settingFile": "/index.js",
"replaceTokens": {
"appId": "Enter_the_Application_Id_Here",
"tenantId": "Enter_the_Tenant_Info_Here",
"clientSecret": "Enter_the_Client_Secret_Here",
"authorityEndpointHost": "Enter_the_Cloud_Instance_Id_Here"
}
}
]
}
]
}

@ -0,0 +1,41 @@
{
"Sample": {
"Title": "A Node.js & Express web app authenticating users against Azure AD with MSAL Node",
"Level": 100,
"Client": "Node.js & Express web app",
"RepositoryUrl": "ms-identity-javascript-nodejs-tutorial",
"Endpoint": "AAD v2.0"
},
"AADApps": [
{
"Id": "webApp",
"Name": "ms-identity-node",
"Kind": "WebApp",
"Audience": "AzureADMyOrg",
"HomePage": "http://localhost:3000",
"ReplyUrls": "http://localhost:3000/redirect",
"PasswordCredentials": "Auto"
}
],
"CodeConfiguration": [
{
"App": "webApp",
"SettingKind": "Replace",
"SettingFile": "\\..\\index.js",
"Mappings": [
{
"key": "Enter_the_Application_Id_Here",
"value": ".AppId"
},
{
"key": "Enter_the_Cloud_Instance_Id_HereEnter_the_Tenant_Info_Here",
"value": "'https://login.microsoftonline.com/common'"
},
{
"key": "Enter_the_Client_Secret_Here",
"value": ".AppKey"
}
]
}
]
}

@ -0,0 +1,13 @@
## [project-title] Changelog
<a name="x.y.z"></a>
# x.y.z (yyyy-mm-dd)
*Features*
* ...
*Bug Fixes*
* ...
*Breaking Changes*
* ...

@ -0,0 +1,76 @@
# Contributing to [project-title]
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
- [Code of Conduct](#coc)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Submission Guidelines](#submit)
## <a name="coc"></a> Code of Conduct
Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
## <a name="issue"></a> Found an Issue?
If you find a bug in the source code or a mistake in the documentation, you can help us by
[submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can
[submit a Pull Request](#submit-pr) with a fix.
## <a name="feature"></a> Want a Feature?
You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub
Repository. If you would like to *implement* a new feature, please submit an issue with
a proposal for your work first, to be sure that we can use it.
* **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
## <a name="submit"></a> Submission Guidelines
### <a name="submit-issue"></a> Submitting an Issue
Before you submit an issue, search the archive, maybe your question was already answered.
If your issue appears to be a bug, and hasn't been reported, open a new issue.
Help us to maximize the effort we can spend fixing issues and adding new
features, by not reporting duplicate issues. Providing the following information will increase the
chances of your issue being dealt with quickly:
* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
* **Version** - what version is affected (e.g. 0.1.2)
* **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you
* **Browsers and Operating System** - is this a problem with all browsers?
* **Reproduce the Error** - provide a live example or a unambiguous set of steps
* **Related Issues** - has a similar issue been reported before?
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
causing the problem (line of code or commit)
You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new].
### <a name="submit-pr"></a> Submitting a Pull Request (PR)
Before you submit your Pull Request (PR) consider the following guidelines:
* Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR
that relates to your submission. You don't want to duplicate effort.
* Make your changes in a new git fork:
* Commit your changes using a descriptive commit message
* Push your fork to GitHub:
* In GitHub, create a pull request
* If we suggest changes then:
* Make the required updates.
* Rebase your fork and force push to your GitHub repository (this will update your Pull Request):
```shell
git rebase master -i
git push -f
```
That's it! Thank you for your contribution!

@ -0,0 +1,11 @@
FROM node
ADD ./ /auth
WORKDIR /auth
RUN npm i
EXPOSE 3000
CMD ["npm", "start"]

@ -0,0 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

@ -0,0 +1,243 @@
---
page_type: sample
languages:
- javascript
products:
- nodejs
- azure-active-directory
description: "Add authentication to a Node.js web application with the Microsoft Authentication Library for Node.js (MSAL Node)."
urlFragment: "quickstart-v2-nodejs-webapp-msal"
---
# Add user authentication to a Node web app with MSAL
This sample Node.js web application uses the Microsoft Authentication Library for Node.js (MSAL Node.js) to sign in users by using the OAuth 2.0 authorization code flow.
You can find additional information about supporting user sign-in in your web apps by using the Microsoft identity platform on docs.microsoft.com: [Scenario: Web app that signs in users](https://docs.microsoft.com/azure/active-directory/develop/scenario-web-app-sign-user-overview?tabs=aspnetcore).
## Prerequisites
- [Node.js](https://nodejs.org/en/)
## Register the application
First, complete the steps in [Register an application with the Microsoft identity platform](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app) to register the app.
Use the following settings for your app registration:
- Name: `MSAL Node Sample` (suggested)
- Supported account types: **Accounts in any organizational directory and personal Microsoft accounts**
- Platform type: **Web**
- Redirect URI: `http://localhost:3000/redirect`
- Client secret: `*********` (record this value after creation - it's shown only once)
## Clone the repository
Next, get the files included in this code sample.
SSH:
```bash
$ git clone git@github.com:AzureAD/ms-identity-node.git
```
HTTP:
```bash
$ git clone https://github.com/AzureAD/ms-identity-node.git
```
You can also download the repository by selecting **Download ZIP** from the repository's dropdown menu. You can decompress it locally and explore the code.
## Install the package
To install the MSAL Node package:
```bash
npm install @azure/msal-node
```
If you are customizing MSAL Node or building locally:
```bash
npm run build:package
```
## Configure the sample code
Open the *index.js* file and find the `config` object. Modify the `config` object with values from your [app's registration in the Azure portal](https://docs.microsoft.com/azure/active-directory/develop/quickstart-register-app).
Find your app's registration in the [Azure portal](https://portal.azure.com) and populate the `config` object with the following values:
* `clientId`: **Application (client) ID**
* `authority`: `https://login.microsoftonline.com/common`
* `clientSecret`: `********` (recorded during app registration - see [Prerequisites](#))
You have finished the basic configuration!
> TIP: You can support different account types by specifying other [authority options](https://docs.microsoft.com/azure/active-directory/develop/msal-client-application-configuration). Unless you have a need to restrict users of your app to a single organization, we suggest you use the default authority shown here. User restrictions can be placed later in the application flow if needed.
## Run the sample app
1. From the command line, let npm install any needed dependencies. This only needs to be done once.
```bash
$ npm install
```
1. Once the dependencies are installed, you can run the sample application by using the following command:
```bash
$ npm start
```
1. Navigate to http://localhost:3000 (or whatever port number specified) with the browser of your choice.
#### Customize application start
To customize the start script, modify the *package.json* file.
## Add authentication to an existing application
### Import the Configuration Object
If you set up the sample with your app registration, you may be able to copy this object directly into your application.
```js
const config = {
auth: {
clientId: "12d77c73-d09d-406a-3asd-3d4e576f7d9b",
authority: "https://login.microsoftonline.com/common",
clientSecret: ""
},
    system: {
        loggerOptions: {
            loggerCallback(loglevel, message, containsPii) {
                console.log(message);
            },
         piiLoggingEnabled: false,
         logLevel: msal.LogLevel.Verbose,
        }
    }
};
```
### Configure Dependencies
Add the dependency on MSAL Node to your Node app.
```js
const msal = require('@azure/msal-node');
```
### Initialize MSAL Node at runtime
Initialize the app object within your web app.
```js
const pca = new msal.ConfidentialClientApplication(config);
```
### Configure sign-in request
Choose the route that requires sign-in. Within that route, set up permissions and direct the MSAL Node app object to attempt sign-in.
In this code sample, the user is immediately signed-in. If you want all users to be logged in before they view anything, then you can use the same process. Add the sign-in code to the default route:
```js
app.get('/', (req, res) => {
```
Next, pick the `scopes` related to the user. If you're logging in a user, you must at minimum request access to basic user information. The default scope of `user.read` grants that basic access. To learn more, see the [Microsoft Graph permissions reference](https://docs.microsoft.com/graph/permissions-reference).
```js
const authCodeUrlParameters = {
scopes: ["user.read"],
redirectUri: "http://localhost:3000/redirect",
};
```
The `redirectUri` is the return route. After logging in a user, they'll hit this route. Your application logic will take over here. You'll want to customize the `redirectUri` for your application.
Next, direct the user to authenticate. The following code block directs the user based on the `authority` you set in the config and directs the user as needed.
```js
pca.getAuthCodeUrl(authCodeUrlParameters).then((response) => {
res.redirect(response);
}).catch((error) => console.log(JSON.stringify(error)));
```
Putting together the routing and all the logic for starting the sign-in yields the following code:
```js
app.get('/', (req, res) => {
const authCodeUrlParameters = {
scopes: ["user.read"],
redirectUri: "http://localhost:3000/redirect",
};
pca.getAuthCodeUrl(authCodeUrlParameters).then((response) => {
res.redirect(response);
}).catch((error) => console.log(JSON.stringify(error)));
});
```
### Configure sign-in response
The next step occurs after the redirect. Your application must first *complete* the sign-in flow by processing the code and validating the incoming request.
First, configure the route where your app should receive the response. This must match your app registration's configuration in the Azure portal.
```js
app.get('/redirect', (req, res) => {
```
Next, your app logic validates the scopes and route. The `scopes` must match the request and the `redirectUri` must match the **Redirect URI** you configured in the app registration in the Azure portal, as well the route.
```js
const tokenRequest = {
code: req.query.code,
scopes: ["user.read"],
redirectUri: "http://localhost:3000/redirect",
};
```
The above code is the *configuration* for validating the response. The following code *validates* the response and completes the sign-in.
```js
pca.acquireTokenByCode(tokenRequest).then((response) => {
console.log("\nResponse: \n:", response);
res.sendStatus(200);
}).catch((error) => {
console.log(error);
res.status(500).send(error);
});
```
Putting together the routing and all the logic for completing the sign-in yields the following code:
```js
app.get('/redirect', (req, res) => {
const tokenRequest = {
code: req.query.code,
scopes: ["user.read"],
redirectUri: "http://localhost:3000/redirect",
};
pca.acquireTokenByCode(tokenRequest).then((response) => {
console.log("\nResponse: \n:", response);
res.sendStatus(200);
}).catch((error) => {
console.log(error);
res.status(500).send(error);
});
});
```
## The user experience
What happens if the user logs in, closes the window, returns to the site, and logs in again?
Microsoft supports several complex scenarios with several forms of authentication: certificates, hardware keys, federated experiences, and even biometrics in some cases. Let our the Microsoft Authentication Library (MSAL) handle the complexity of deciding the simplest way of logging in the user.
> NOTE: Silent flows are not used with this scenario. See [Authentication flows](https://docs.microsoft.com/azure/active-directory/develop/msal-authentication-flows) for a discussion of the interaction between flows.

@ -0,0 +1,66 @@
/*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
const express = require("express");
const msal = require('@azure/msal-node');
const SERVER_PORT = process.env.PORT || 3000;
const REDIRECT_URI = "https://citrix.node4co.uk/redirect";
// Before running the sample, you will need to replace the values in the config,
// including the clientSecret
const config = {
auth: {
clientId: "769b81fe-3663-4034-824f-8c07f3a74138",
authority: "https://login.microsoftonline.com/common",
clientSecret: process.env.secret
},
    system: {
        loggerOptions: {
            loggerCallback(loglevel, message, containsPii) {
                console.log(message);
            },
         piiLoggingEnabled: false,
         logLevel: msal.LogLevel.Verbose,
        }
    }
};
// Create msal application object
const pca = new msal.ConfidentialClientApplication(config);
// Create Express App and Routes
const app = express();
app.get('/', (req, res) => {
const authCodeUrlParameters = {
scopes: ["user.read"],
redirectUri: REDIRECT_URI,
};
// get url to sign user in and consent to scopes needed for application
pca.getAuthCodeUrl(authCodeUrlParameters).then((response) => {
res.redirect(response);
}).catch((error) => console.log(JSON.stringify(error)));
});
app.get('/redirect', (req, res) => {
res.redirect(302, 'https://citrix.node4.co.uk');
// const tokenRequest = {
// code: req.query.code,
// scopes: ["user.read"],
// redirectUri: REDIRECT_URI,
// };
// pca.acquireTokenByCode(tokenRequest).then((response) => {
// console.log("\nResponse: \n:", response);
// res.sendStatus(200);
// }).catch((error) => {
// console.log(error);
// res.status(500).send(error);
// });
});
app.listen(SERVER_PORT, () => console.log(`Msal Node Auth Code Sample app listening on port ${SERVER_PORT}!`))

1269
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,16 @@
{
"name": "msal-node-auth-code",
"version": "1.0.0",
"description": "sample app for msal-node",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"author": "Microsoft",
"license": "MIT",
"dependencies": {
"@azure/msal-node": "^1.0.0",
"express": "^4.17.1",
"uuid": "^8.3.1"
}
}
Loading…
Cancel
Save