diff --git a/README.md b/README.md index b1361c685c..faa8edd72e 100644 --- a/README.md +++ b/README.md @@ -75,8 +75,8 @@ Samples are designed to illustrate functionality you'll need to implement to bui |18|OAuth authentication | Bot that demonstrates how to integrate OAuth providers. |[.NET Core][cs#18]|[JavaScript][js#18]|[Python][py#18]|[Java][java#18] |24|MSGraph authentication | Demonstrates bot authentication capabilities of Azure Bot Service. Demonstrates utilizing the Microsoft Graph API to retrieve data about the user.|[.NET Core][cs#24] |[JavaScript][js#24] |[Python][py#24]|[Java][java#24] |46|Teams authentication | Demonstrates how to use authentication for a bot running in Microsoft Teams. | [.NET Core](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-teams-authentication/csharp) | [JavaScript](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-conversation-sso-quickstart/js) |[Python](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-teams-authentication/python)|[Java](https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-teams-authentication/java) -|84|Certificate authentication | Demonstrates how to use Certificates to authenticate the bot | [.NET Core][cs#84] |[JavaScript][js#84] | | -|85|Subject name/issuer authentication | Demonstrates how to use the subject name/issuer authentication in a bot | [.NET Core][cs#85] | | | +|84|Certificate authentication | Demonstrates how to use Certificates to authenticate the bot | [.NET Core][cs#84] |[JavaScript][js#84] | | +|85|Subject name/issuer authentication | Demonstrates how to use the subject name/issuer authentication in a bot | [.NET Core][cs#85] | [JavaScript][js#85] | | ### Custom question answering samples @@ -188,6 +188,7 @@ A [collection of **experimental** samples](./experimental) exist, intended to pr [js#81]:samples/javascript_nodejs/81.skills-skilldialog [js#82]:samples/javascript_nodejs/82.skills-sso-cloudadapter [js#84]:samples/javascript_nodejs/84.bot-authentication-certificate +[js#85]:samples/javascript_nodejs/85.bot-authentication-sni [py#1]:samples/python/01.console-echo [py#2]:samples/python/02.echo-bot diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/.env b/samples/javascript_nodejs/85.bot-authentication-sni/.env new file mode 100644 index 0000000000..689b8040bd --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/.env @@ -0,0 +1,6 @@ +MicrosoftAppType= +MicrosoftAppId= +MicrosoftAppTenantId= +CertificateThumbprint= +KeyVaultName= +CertificateName= diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/.eslintrc.js b/samples/javascript_nodejs/85.bot-authentication-sni/.eslintrc.js new file mode 100644 index 0000000000..43b3d45dd2 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/.eslintrc.js @@ -0,0 +1,15 @@ +/* eslint-disable */ +module.exports = { + "extends": "standard", + "rules": { + "semi": [2, "always"], + "indent": [2, 4], + "no-return-await": 0, + "space-before-function-paren": [2, { + "named": "never", + "anonymous": "never", + "asyncArrow": "always" + }], + "template-curly-spacing": [2, "always"] + } +}; \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/README.md b/samples/javascript_nodejs/85.bot-authentication-sni/README.md new file mode 100644 index 0000000000..db9616eb2e --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/README.md @@ -0,0 +1,140 @@ +# Authentication Bot using Subject Name/Issuer + +Bot Framework v4 bot authentication using Subject Name/Issuer + +This bot has been created using [Bot Framework](https://dev.botframework.com/), is shows how to use the bot authentication capabilities of Azure Bot Service. In this sample, we use a local or KeyVault certificate and the MSAL Subject Name/Issuer configuration to create the Bot Framework Authentication. + +## Prerequisites + +- [Node.js](https://nodejs.org) version 10.14 or higher + +```bash +# determine node version +node --version +``` + +## To try this sample + +- Clone the repository + +```bash +git clone https://github.com/microsoft/botbuilder-samples.git +``` + +- In a terminal, navigate to `samples/javascript_nodejs/85.bot-authentication-sni` + +```bash +cd samples/javascript_nodejs/85.bot-authentication-sni +``` + +- Install modules + +```bash +npm install +``` + +- Set environment variables + + - MicrosoftAppType: Type of the App. + + - MicrosoftAppId: App Id of your bot. + + - MicrosoftAppTenantId: Tenant Id to which your bot belongs. + + - CertificateThumbprint: Certificate thumbprint. + + - KeyVaultName: Name of the KeyVault containing the certificate. + + - CertificateName: Name of the certificate in the KeyVault. + +- Start the bot + +```bash +npm start +``` + +## Testing the bot using Bot Framework Emulator + +[Bot Framework Emulator](https://github.com/microsoft/botframework-emulator) is a desktop application that allows bot developers to test and debug their bots on localhost or running remotely through a tunnel. + +- Install the latest Bot Framework Emulator from [here](https://github.com/Microsoft/BotFramework-Emulator/releases) + +### Connect to the bot using Bot Framework Emulator + +- Launch Bot Framework Emulator + +- File -> Open Bot + +- Enter a Bot URL of `http://localhost:3978/api/messages` + +## Interacting with the bot + +This sample uses the bot authentication capabilities of Azure Bot Service, providing features to make it easier to develop a bot that authenticates users using digital security certificates. You just need to provide the certificate data linked to the managed identity and run the bot, then communicate with it to validate its correct authentication. + +## SSL/TLS certificate + +An SSL/TLS certificate is a digital object that allows systems to verify identity and subsequently establish an encrypted network connection with another system using the Secure Sockets Layer/Transport Layer Security (SSL/TLS) protocol. Certificates are issued using a cryptographic system known as public key infrastructure (PKI). PKI allows one party to establish the identity of another through the use of certificates if they both trust a third party, known as a certificate authority. SSL/TLS certificates therefore function as digital identity documents that protect network communications and establish the identity of websites on the Internet as well as resources on private networks. + +## How to create an SSL/TLS certificate + +There are two possible options to create SSL/TSL certificate. Below is a step-by-step description of each one: + +### Using local environment + +1. Run the following command in a local PowerShell + +``` +$cert = New-SelfSignedCertificate -CertStoreLocation "" -Subject "CN=" -KeySpec KeyExchange +``` + +1. Then, type _Manage User Certificates_ in the Windows search bar and hit enter + +2. The certificate will be located in the _user certificates_ folder, under _personal_ directory. + +3. Export the certificate to _pfx_ format including the key(The default location is _system32_ folder). + +4. Go to the certificate location and run the following command to generate a _pem_ file: + +``` +OpenSSL pkcs12 -in .pfx -out c:\.pem –nodes +``` + +5. Upload the generated certificate to the Azure app registration. + +### Using KeyVault + +1. Create a KeyVault resource and assign _the KeyVault Administrator_ role to have permission to create a new certificate. + +2. Under the Certificates section, hit on Generate/Import, complete the form, and create the certificate in PEM format. + +3. Go to the details of the certificate that you created and enable it. + +4. Download the certificate in CER format and then upload it to the Azure app registration. + +## Deploy the bot to Azure + +To learn more about deploying a bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) for a complete list of deployment instructions. + +## Further reading + +- [Bot Framework Documentation](https://docs.botframework.com) + +- [Bot Basics](https://docs.microsoft.com/azure/bot-service/bot-builder-basics?view=azure-bot-service-4.0) + +- [Activity processing](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-concept-activity-processing?view=azure-bot-service-4.0) + +- [Azure Bot Service Introduction](https://docs.microsoft.com/azure/bot-service/bot-service-overview-introduction?view=azure-bot-service-4.0) + +- [Azure Bot Service Documentation](https://docs.microsoft.com/azure/bot-service/?view=azure-bot-service-4.0) + +- [Azure CLI](https://docs.microsoft.com/cli/azure/?view=azure-cli-latest) + +- [Azure Portal](https://portal.azure.com) + +- [Channels and Bot Connector Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-concepts?view=azure-bot-service-4.0) + +- [Restify](https://www.npmjs.com/package/restify) + +- [dotenv](https://www.npmjs.com/package/dotenv) + +- [SSL/TLS certificates](https://www.digicert.com/tls-ssl/tls-ssl-certificates) diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/authBot.js b/samples/javascript_nodejs/85.bot-authentication-sni/authBot.js new file mode 100644 index 0000000000..f1bf96706a --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/authBot.js @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const { ActivityHandler, MessageFactory } = require('botbuilder'); + +class AuthBot extends ActivityHandler { + constructor() { + super(); + // See https://aka.ms/about-bot-activity-message to learn more about the message and other activity types. + this.onMessage(async (context, next) => { + const replyText = 'Running dialog with bot authenticated'; + const message = MessageFactory.text(replyText, replyText); + await context.sendActivity(message); + // By calling next() you ensure that the next BotHandler is run. + await next(); + }); + + this.onMembersAdded(async (context, next) => { + const membersAdded = context.activity.membersAdded; + const welcomeText = 'Welcome to the Bot with Subject Name/Issuer Authentication'; + for (let cnt = 0; cnt < membersAdded.length; ++cnt) { + if (membersAdded[cnt].id !== context.activity.recipient.id) { + await context.sendActivity(MessageFactory.text(welcomeText, welcomeText)); + } + } + // By calling next() you ensure that the next BotHandler is run. + await next(); + }); + } +} + +module.exports.AuthBot = AuthBot; diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/linux/.deployment b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/linux/.deployment new file mode 100644 index 0000000000..1047846624 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/linux/.deployment @@ -0,0 +1,2 @@ +[config] +command = ./deploy.sh \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/linux/deploy.sh b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/linux/deploy.sh new file mode 100644 index 0000000000..8c02d427cc --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/linux/deploy.sh @@ -0,0 +1,100 @@ +#!/bin/bash + +# ---------------------- +# KUDU Deployment Script +# Version: 1.0.17 +# ---------------------- + +# Helpers +# ------- + +exitWithMessageOnError () { + if [ ! $? -eq 0 ]; then + echo "An error has occurred during web site deployment." + echo $1 + exit 1 + fi +} + +# Prerequisites +# ------------- + +# Verify node.js installed +hash node 2>/dev/null +exitWithMessageOnError "Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment." + +# Setup +# ----- + +SCRIPT_DIR="${BASH_SOURCE[0]%\\*}" +SCRIPT_DIR="${SCRIPT_DIR%/*}" +ARTIFACTS=$SCRIPT_DIR/../artifacts +KUDU_SYNC_CMD=${KUDU_SYNC_CMD//\"} + +if [[ ! -n "$DEPLOYMENT_SOURCE" ]]; then + DEPLOYMENT_SOURCE=$SCRIPT_DIR +fi + +if [[ ! -n "$NEXT_MANIFEST_PATH" ]]; then + NEXT_MANIFEST_PATH=$ARTIFACTS/manifest + + if [[ ! -n "$PREVIOUS_MANIFEST_PATH" ]]; then + PREVIOUS_MANIFEST_PATH=$NEXT_MANIFEST_PATH + fi +fi + +if [[ ! -n "$DEPLOYMENT_TARGET" ]]; then + DEPLOYMENT_TARGET=$ARTIFACTS/wwwroot +else + KUDU_SERVICE=true +fi + +if [[ ! -n "$KUDU_SYNC_CMD" ]]; then + # Install kudu sync + echo Installing Kudu Sync + npm install kudusync -g --silent + exitWithMessageOnError "npm failed" + + if [[ ! -n "$KUDU_SERVICE" ]]; then + # In case we are running locally this is the correct location of kuduSync + KUDU_SYNC_CMD=kuduSync + else + # In case we are running on kudu service this is the correct location of kuduSync + KUDU_SYNC_CMD=$APPDATA/npm/node_modules/kuduSync/bin/kuduSync + fi +fi + +# Node Helpers +# ------------ + +selectNodeVersion () { + NPM_CMD=npm + NODE_EXE=node +} + +################################################################################################################################## +# Deployment +# ---------- + +echo Handling node.js deployment. + +# 1. KuduSync +if [[ "$IN_PLACE_DEPLOYMENT" -ne "1" ]]; then + "$KUDU_SYNC_CMD" -v 50 -f "$DEPLOYMENT_SOURCE" -t "$DEPLOYMENT_TARGET" -n "$NEXT_MANIFEST_PATH" -p "$PREVIOUS_MANIFEST_PATH" -i ".git;.hg;.deployment;deploy.sh" + exitWithMessageOnError "Kudu Sync failed" +fi + +# 2. Select node version +selectNodeVersion + +# 3. Install npm packages +if [ -e "$DEPLOYMENT_TARGET/package.json" ]; then + cd "$DEPLOYMENT_TARGET" + echo "Running $NPM_CMD install --production" + eval $NPM_CMD install --production + exitWithMessageOnError "npm failed" + cd - > /dev/null +fi + +################################################################################################################################## +echo "Finished successfully." \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/windows/.deployment b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/windows/.deployment new file mode 100644 index 0000000000..db5488a1df --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/windows/.deployment @@ -0,0 +1,2 @@ +[config] +command = deploy.cmd \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/windows/deploy.cmd b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/windows/deploy.cmd new file mode 100644 index 0000000000..7a40dcabf5 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentScripts/windows/deploy.cmd @@ -0,0 +1,133 @@ +@if "%SCM_TRACE_LEVEL%" NEQ "4" @echo off + +:: ---------------------- +:: KUDU Deployment Script +:: Version: 1.0.17 +:: ---------------------- + +:: Prerequisites +:: ------------- + +:: Verify node.js installed +where node 2>nul >nul +IF %ERRORLEVEL% NEQ 0 ( + echo Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment. + goto error +) + +:: Setup +:: ----- + +setlocal enabledelayedexpansion + +SET ARTIFACTS=%~dp0%..\artifacts + +IF NOT DEFINED DEPLOYMENT_SOURCE ( + SET DEPLOYMENT_SOURCE=%~dp0%. +) + +IF NOT DEFINED DEPLOYMENT_TARGET ( + SET DEPLOYMENT_TARGET=%ARTIFACTS%\wwwroot +) + +IF NOT DEFINED NEXT_MANIFEST_PATH ( + SET NEXT_MANIFEST_PATH=%ARTIFACTS%\manifest + + IF NOT DEFINED PREVIOUS_MANIFEST_PATH ( + SET PREVIOUS_MANIFEST_PATH=%ARTIFACTS%\manifest + ) +) + +IF NOT DEFINED KUDU_SYNC_CMD ( + :: Install kudu sync + echo Installing Kudu Sync + call npm install kudusync -g --silent + IF !ERRORLEVEL! NEQ 0 goto error + + :: Locally just running "kuduSync" would also work + SET KUDU_SYNC_CMD=%appdata%\npm\kuduSync.cmd +) +goto Deployment + +:: Utility Functions +:: ----------------- + +:SelectNodeVersion + +IF DEFINED KUDU_SELECT_NODE_VERSION_CMD ( + :: The following are done only on Windows Azure Websites environment + call %KUDU_SELECT_NODE_VERSION_CMD% "%DEPLOYMENT_SOURCE%" "%DEPLOYMENT_TARGET%" "%DEPLOYMENT_TEMP%" + IF !ERRORLEVEL! NEQ 0 goto error + + IF EXIST "%DEPLOYMENT_TEMP%\__nodeVersion.tmp" ( + SET /p NODE_EXE=<"%DEPLOYMENT_TEMP%\__nodeVersion.tmp" + IF !ERRORLEVEL! NEQ 0 goto error + ) + + IF EXIST "%DEPLOYMENT_TEMP%\__npmVersion.tmp" ( + SET /p NPM_JS_PATH=<"%DEPLOYMENT_TEMP%\__npmVersion.tmp" + IF !ERRORLEVEL! NEQ 0 goto error + ) + + IF NOT DEFINED NODE_EXE ( + SET NODE_EXE=node + ) + + SET NPM_CMD="!NODE_EXE!" "!NPM_JS_PATH!" +) ELSE ( + SET NPM_CMD=npm + SET NODE_EXE=node +) + +goto :EOF + +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: Deployment +:: ---------- + +:Deployment +echo Handling node.js deployment. + +:: 1. KuduSync +IF /I "%IN_PLACE_DEPLOYMENT%" NEQ "1" ( + call :ExecuteCmd "%KUDU_SYNC_CMD%" -v 50 -f "%DEPLOYMENT_SOURCE%" -t "%DEPLOYMENT_TARGET%" -n "%NEXT_MANIFEST_PATH%" -p "%PREVIOUS_MANIFEST_PATH%" -i ".git;.hg;.deployment;deploy.cmd" + IF !ERRORLEVEL! NEQ 0 goto error +) + +:: 2. Select node version +call :SelectNodeVersion + +:: 3. Install npm packages +IF EXIST "%DEPLOYMENT_TARGET%\package.json" ( + pushd "%DEPLOYMENT_TARGET%" + call :ExecuteCmd !NPM_CMD! install --production + IF !ERRORLEVEL! NEQ 0 goto error + popd +) + +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +goto end + +:: Execute command routine that will echo out when error +:ExecuteCmd +setlocal +set _CMD_=%* +call %_CMD_% +if "%ERRORLEVEL%" NEQ "0" echo Failed exitCode=%ERRORLEVEL%, command=%_CMD_% +exit /b %ERRORLEVEL% + +:error +endlocal +echo An error has occurred during web site deployment. +call :exitSetErrorLevel +call :exitFromFunction 2>nul + +:exitSetErrorLevel +exit /b 1 + +:exitFromFunction +() + +:end +endlocal +echo Finished successfully. diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json new file mode 100644 index 0000000000..c2c03ef307 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json new file mode 100644 index 0000000000..c4b2909008 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "value": "" + }, + "existingAppServicePlanName": { + "value": "" + }, + "existingAppServicePlanLocation": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanLocation": { + "value": "" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/readme.md b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/readme.md new file mode 100644 index 0000000000..ba81e5b608 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/readme.md @@ -0,0 +1,38 @@ +# Usage +BotApp must be deployed prior to AzureBot. + +### Command line: +`az login`
+`az deployment group create --resource-group --template-file --parameters @` + +## Parameters for template-BotApp-with-rg.json: + +- **appServiceName**: (required) The Name of the Bot App Service. +- (Pick an existing App Service Plan or create a new App Service Plan.) + - **existingAppServicePlanName**: The name of the App Service Plan. + - **existingAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanName**: The name of the App Service Plan. + - **newAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. **Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI.** +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **appSecret**: (required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. +- **UMSIName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to Subscription Tenant ID. + +More info: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource + +## Parameters for template-AzureBot-with-rg.json: + +- **azureBotId**: (required) The globally unique and immutable bot ID. +- **azureBotSku**: The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default). +- **azureBotRegion**: Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope. +- **botEndpoint**: Use to handle client messages, Such as `https://.azurewebsites.net/api/messages`. +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **UMSIName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to Subscription Tenant ID. + +More info: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/template-AzureBot-with-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/template-AzureBot-with-rg.json new file mode 100644 index 0000000000..a8a960066f --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/template-AzureBot-with-rg.json @@ -0,0 +1,121 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default)." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope." + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + } + }, + "variables": { + "botEndpoint": "[if(empty(parameters('botEndpoint')), concat('https://', parameters('azureBotId'), '.azurewebsites.net/api/messages'), parameters('botEndpoint'))]", + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "msiResourceId": "" + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "" + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "[variables('msiResourceId')]" + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "msiResourceId": "[variables('appTypeDef')[parameters('appType')].msiResourceId]" + } + }, + "resources": [ + { + "apiVersion": "2021-05-01-preview", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "msaAppTenantId": "[variables('appType').tenantId]", + "msaAppMSIResourceId": "[variables('appType').msiResourceId]", + "msaAppType": "[parameters('appType')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + }, + "dependsOn": [] + } + ] +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json new file mode 100644 index 0000000000..62a42c9a5d --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployUseExistResourceGroup/template-BotApp-with-rg.json @@ -0,0 +1,191 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "existingAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "existingAppServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types. Defaults to \"\"." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication. Defaults to \"\"." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. Defaults to \"\"." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + } + }, + "variables": { + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "useExistingServicePlan": "[not(empty(parameters('existingAppServicePlanName')))]", + "servicePlanName": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanName'), parameters('newAppServicePlanName'))]", + "servicePlanLocation": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanLocation'), parameters('newAppServicePlanLocation'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "identity": { "type": "None" } + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "identity": { "type": "None" } + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[variables('msiResourceId')]": {} + } + } + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "identity": "[variables('appTypeDef')[parameters('appType')].identity]" + } + }, + "resources": [ + { + "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[parameters('newAppServicePlanLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "properties": { + "name": "[variables('servicePlanName')]" + } + }, + { + "comments": "Create a Web App using an App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('servicePlanLocation')]", + "kind": "app", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]" + ], + "name": "[parameters('appServiceName')]", + "identity": "[variables('appType').identity]", + "properties": { + "name": "[parameters('appServiceName')]", + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]", + "siteConfig": { + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "16.20.2" + }, + { + "name": "MicrosoftAppType", + "value": "[parameters('appType')]" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + }, + { + "name": "MicrosoftAppTenantId", + "value": "[variables('appType').tenantId]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + } + ] +} diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json new file mode 100644 index 0000000000..44f169e4d5 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json @@ -0,0 +1,39 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json new file mode 100644 index 0000000000..8abb03d597 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json @@ -0,0 +1,48 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "appServiceName": { + "value": "" + }, + "appServicePlanName": { + "value": "" + }, + "appServicePlanLocation": { + "value": "" + }, + "appServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "appType": { + "value": "MultiTenant" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "UMSIName": { + "value": "" + }, + "UMSIResourceGroupName": { + "value": "" + }, + "tenantId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/readme.md b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/readme.md new file mode 100644 index 0000000000..2f2571d06d --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/readme.md @@ -0,0 +1,45 @@ +# Usage +BotApp must be deployed prior to AzureBot. + +### Command line: +`az login`
+`az deployment sub create --template-file --location --parameters @` + +## Parameters for template-BotApp-new-rg.json: + +- **groupName**: (required) The name of the new Resource Group. +- **groupLocation**: (required) The location of the new Resource Group. + +- **appServiceName**: (required) The location of the App Service Plan. +- **appServicePlanName**: (required) The name of the App Service Plan. +- **appServicePlanLocation**: The location of the App Service Plan. Defaults to use groupLocation. +- **appServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **appSecret**: (required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. +- **UMSIName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**:(required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to . + +More info: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource + + + +## Parameters for template-AzureBot-new-rg.json: + +- **groupName**: (required) The name of the new Resource Group. +- **groupLocation**: (required) The location of the new Resource Group. + +- **azureBotId**: (required) The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable. +- **azureBotSku**: The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default). +- **azureBotRegion**: Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope. +- **botEndpoint**: Use to handle client messages, Such as `https://.azurewebsites.net/api/messages`. + +- **appType**: Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant(default), SingleTenant, UserAssignedMSI. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **UMSIName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource used for the Bot's Authentication. +- **UMSIResourceGroupName**: (required for UserAssignedMSI) The User-Assigned Managed Identity Resource Group used for the Bot's Authentication. +- **tenantId**: The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to Subscription Tenant ID. + +More info: https://docs.microsoft.com/en-us/azure/bot-service/tutorial-provision-a-bot?view=azure-bot-service-4.0&tabs=userassigned%2Cnewgroup#create-an-identity-resource \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/template-AzureBot-new-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/template-AzureBot-new-rg.json new file mode 100644 index 0000000000..ae073b7939 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/template-AzureBot-new-rg.json @@ -0,0 +1,160 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "" + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + } + }, + "variables": { + "botEndpoint": "[if(empty(parameters('botEndpoint')), concat('https://', parameters('azureBotId'), '.azurewebsites.net/api/messages'), parameters('botEndpoint'))]", + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "msiResourceId": "" + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "" + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "msiResourceId": "[variables('msiResourceId')]" + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "msiResourceId": "[variables('appTypeDef')[parameters('appType')].msiResourceId]" + } + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "apiVersion": "2021-03-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "name": "[parameters('azureBotId')]", + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "msaAppTenantId": "[variables('appType').tenantId]", + "msaAppMSIResourceId": "[variables('appType').msiResourceId]", + "msaAppType": "[parameters('appType')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/template-BotApp-new-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/template-BotApp-new-rg.json new file mode 100644 index 0000000000..caafb9ba0a --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/deployWithNewResourceGroup/template-BotApp-new-rg.json @@ -0,0 +1,213 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "appServiceName": { + "type": "string", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "appServicePlanName": { + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "appServicePlanLocation": { + "type": "string", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "appServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "tenantId": { + "type": "string", + "defaultValue": "[subscription().tenantId]", + "metadata": { + "description": "The Azure AD Tenant ID to use as part of the Bot's Authentication. Only used for SingleTenant and UserAssignedMSI app types. Defaults to \"Subscription Tenant ID\"." + } + }, + "appType": { + "type": "string", + "defaultValue": "MultiTenant", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ], + "metadata": { + "description": "Type of Bot Authentication. set as MicrosoftAppType in the Web App's Application Settings. Allowed values are: MultiTenant, SingleTenant, UserAssignedMSI. Defaults to \"MultiTenant\"." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types." + } + }, + "UMSIName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource used for the Bot's Authentication." + } + }, + "UMSIResourceGroupName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The User-Assigned Managed Identity Resource Group used for the Bot's Authentication." + } + } + }, + "variables": { + "tenantId": "[if(empty(parameters('tenantId')), subscription().tenantId, parameters('tenantId'))]", + "appServicePlanName": "[parameters('appServicePlanName')]", + "resourcesLocation": "[if(empty(parameters('appServicePlanLocation')), parameters('groupLocation'), parameters('appServicePlanLocation'))]", + "appServiceName": "[parameters('appServiceName')]", + "resourceGroupId": "[concat(subscription().id, '/resourceGroups/', parameters('groupName'))]", + "msiResourceId": "[if(empty(parameters('UMSIName')), '', concat(subscription().id, '/resourceGroups/', parameters('UMSIResourceGroupName'), '/providers/', 'Microsoft.ManagedIdentity/userAssignedIdentities/', parameters('UMSIName')))]", + "appTypeDef": { + "MultiTenant": { + "tenantId": "", + "identity": { "type": "None" } + }, + "SingleTenant": { + "tenantId": "[variables('tenantId')]", + "identity": { "type": "None" } + }, + "UserAssignedMSI": { + "tenantId": "[variables('tenantId')]", + "identity": { + "type": "UserAssigned", + "userAssignedIdentities": { + "[variables('msiResourceId')]": {} + } + } + } + }, + "appType": { + "tenantId": "[variables('appTypeDef')[parameters('appType')].tenantId]", + "identity": "[variables('appTypeDef')[parameters('appType')].identity]" + } + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new App Service Plan", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('appServicePlanSku')]", + "properties": { + "name": "[variables('appServicePlanName')]" + } + }, + { + "comments": "Create a Web App using the new App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "location": "[variables('resourcesLocation')]", + "kind": "app", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "name": "[variables('appServiceName')]", + "identity": "[variables('appType').identity]", + "properties": { + "name": "[variables('appServiceName')]", + "serverFarmId": "[variables('appServicePlanName')]", + "siteConfig": { + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "16.20.2" + }, + { + "name": "MicrosoftAppType", + "value": "[parameters('appType')]" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + }, + { + "name": "MicrosoftAppTenantId", + "value": "[variables('appType').tenantId]" + } + ], + "cors": { + "allowedOrigins": [ + "https://botservice.hosting.portal.azure.net", + "https://hosting.onecloud.azure-test.net/" + ] + }, + "webSocketsEnabled": true + } + } + } + ], + "outputs": {} + } + } + } + ] +} diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json new file mode 100644 index 0000000000..cc1800c0db --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/parameters-for-template-AzureBot-with-rg.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json new file mode 100644 index 0000000000..c1f341b084 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/parameters-for-template-BotApp-with-rg.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "value": "" + }, + "existingAppServicePlanName": { + "value": "" + }, + "existingAppServicePlanLocation": { + "value": "" + }, + "newAppServicePlanName": { + "value": "" + }, + "newAppServicePlanLocation": { + "value": "West US" + }, + "newAppServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "linuxFxVersion": { + "value": "" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "appType": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/readme.md b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/readme.md new file mode 100644 index 0000000000..93086e1f57 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/readme.md @@ -0,0 +1,26 @@ +# Usage +BotApp must be deployed prior to AzureBot. + +### Command line: +`az login`
+`az deployment group create --resource-group --template-file --parameters @` + +## Parameters for template-BotApp-with-rg.json: + +- **appServiceName**: (required) The Name of the Bot App Service. +- (Pick an existing App Service Plan or create a new App Service Plan.) + - **existingAppServicePlanName**: The name of the App Service Plan. + - **existingAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanName**: The name of the App Service Plan. + - **newAppServicePlanLocation**: The location of the App Service Plan. + - **newAppServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **appSecret**: (required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. + +## Parameters for template-AzureBot-with-rg.json: + +- **azureBotId**: (required) The globally unique and immutable bot ID. +- **azureBotSku**: The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default). +- **azureBotRegion**: Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope. +- **botEndpoint**: Use to handle client messages, Such as `https://.azurewebsites.net/api/messages`. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/template-AzureBot-with-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/template-AzureBot-with-rg.json new file mode 100644 index 0000000000..60c9c1bb6c --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/template-AzureBot-with-rg.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default)." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope." + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + } + }, + "variables": { + "botEndpoint": "[if(empty(parameters('botEndpoint')), concat('https://', parameters('azureBotId'), '.azurewebsites.net/api/messages'), parameters('botEndpoint'))]" + }, + "resources": [ + { + "apiVersion": "2021-05-01-preview", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "name": "[parameters('azureBotId')]", + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + } + } + ] +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/template-BotApp-with-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/template-BotApp-with-rg.json new file mode 100644 index 0000000000..d588b44a4b --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployUseExistResourceGroup/template-BotApp-with-rg.json @@ -0,0 +1,221 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "appServiceName": { + "type": "string", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "existingAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of the existing App Service Plan used to create the Web App for the bot." + } + }, + "existingAppServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The name of the new App Service Plan." + } + }, + "newAppServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "newAppServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "linuxFxVersion": { + "type": "string", + "defaultValue": "NODE|16.20" + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types. Defaults to \"\"." + } + }, + "appType": { + "defaultValue": "MultiTenant", + "type": "string", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ] + } + }, + "variables": { + "useExistingServicePlan": "[not(empty(parameters('existingAppServicePlanName')))]", + "servicePlanName": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanName'), parameters('newAppServicePlanName'))]", + "servicePlanLocation": "[if(variables('useExistingServicePlan'), parameters('existingAppServicePlanLocation'), parameters('newAppServicePlanLocation'))]" + }, + "resources": [ + { + "comments": "Create a new App Service Plan if no existing App Service Plan name was passed in.", + "type": "Microsoft.Web/serverfarms", + "condition": "[not(variables('useExistingServicePlan'))]", + "name": "[variables('servicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[parameters('newAppServicePlanLocation')]", + "sku": "[parameters('newAppServicePlanSku')]", + "kind": "linux", + "properties": { + "name": "[variables('servicePlanName')]", + "perSiteScaling": false, + "reserved": true, + "targetWorkerCount": 0, + "targetWorkerSizeId": 0 + } + }, + { + "comments": "Create a Web App using an App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "name": "[parameters('appServiceName')]", + "location": "[variables('servicePlanLocation')]", + "kind": "app,linux", + "dependsOn": [ + "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]" + ], + "properties": { + "enabled": true, + "hostNameSslStates": [ + { + "name": "[concat(parameters('appServiceName'), '.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Standard" + }, + { + "name": "[concat(parameters('appServiceName'), '.scm.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Repository" + } + ], + "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('servicePlanName'))]", + "reserved": true, + "scmSiteAlsoStopped": false, + "clientAffinityEnabled": false, + "clientCertEnabled": false, + "hostNamesDisabled": false, + "containerSize": 0, + "dailyMemoryTimeQuota": 0, + "httpsOnly": false, + "siteConfig": { + "linuxFxVersion": "[parameters('linuxFxVersion')]", + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "16.20.2" + }, + { + "name": "MicrosoftAppType", + "value": "[parameters('appType')]" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ] + } + } + }, + { + "type": "Microsoft.Web/sites/config", + "apiVersion": "2016-08-01", + "name": "[concat(parameters('appServiceName'), '/web')]", + "location": "[variables('servicePlanLocation')]", + "dependsOn": [ + "[resourceId('Microsoft.Web/sites', parameters('appServiceName'))]" + ], + "properties": { + "numberOfWorkers": 1, + "defaultDocuments": [ + "Default.htm", + "Default.html", + "Default.asp", + "index.htm", + "index.html", + "iisstart.htm", + "default.aspx", + "index.php", + "hostingstart.html" + ], + "netFrameworkVersion": "v4.0", + "phpVersion": "", + "pythonVersion": "", + "nodeVersion": "", + "linuxFxVersion": "[parameters('linuxFxVersion')]", + "requestTracingEnabled": false, + "remoteDebuggingEnabled": false, + "httpLoggingEnabled": false, + "logsDirectorySizeLimit": 35, + "detailedErrorLoggingEnabled": false, + "publishingUsername": "[concat('$', parameters('appServiceName'))]", + "scmType": "LocalGit", + "use32BitWorkerProcess": true, + "webSocketsEnabled": false, + "alwaysOn": true, + "appCommandLine": "", + "managedPipelineMode": "Integrated", + "virtualApplications": [ + { + "virtualPath": "/", + "physicalPath": "site\\wwwroot", + "preloadEnabled": true, + "virtualDirectories": null + } + ], + "winAuthAdminState": 0, + "winAuthTenantState": 0, + "customAppPoolIdentityAdminState": false, + "customAppPoolIdentityTenantState": false, + "loadBalancing": "LeastRequests", + "routingRules": [], + "experiments": { + "rampUpRules": [] + }, + "autoHealEnabled": false, + "vnetName": "", + "minTlsVersion": "1.2", + "ftpsState": "AllAllowed", + "reservedInstanceCount": 0 + } + } + ] +} diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json new file mode 100644 index 0000000000..f180618138 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/parameters-for-template-AzureBot-new-rg.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "azureBotId": { + "value": "" + }, + "azureBotSku": { + "value": "S1" + }, + "azureBotRegion": { + "value": "global" + }, + "botEndpoint": { + "value": "" + }, + "appId": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json new file mode 100644 index 0000000000..a147121303 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/parameters-for-template-BotApp-new-rg.json @@ -0,0 +1,42 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "value": "" + }, + "groupLocation": { + "value": "" + }, + "appServiceName": { + "value": "" + }, + "appServicePlanName": { + "value": "" + }, + "appServicePlanLocation": { + "value": "" + }, + "appServicePlanSku": { + "value": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + } + }, + "linuxFxVersion": { + "value": "" + }, + "appId": { + "value": "" + }, + "appSecret": { + "value": "" + }, + "appType": { + "value": "" + } + } +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/readme.md b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/readme.md new file mode 100644 index 0000000000..dbdfabf9a9 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/readme.md @@ -0,0 +1,27 @@ +# Usage +BotApp must be deployed prior to AzureBot. + +### Command line: +`az login`
+`az deployment sub create --template-file --location --parameters @` + +## Parameters for template-BotApp-new-rg.json: + +- **groupName**: (required) The name of the new Resource Group. +- **groupLocation**: (required) The location of the new Resource Group. +- **appServiceName**: (required) The location of the App Service Plan. +- **appServicePlanName**: (required) The name of the App Service Plan. +- **appServicePlanLocation**: The location of the App Service Plan. Defaults to use groupLocation. +- **appServicePlanSku**: The SKU of the App Service Plan. Defaults to Standard values. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. +- **appSecret**: (required for MultiTenant and SingleTenant) Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. + +## Parameters for template-AzureBot-new-rg.json: + +- **groupName**: (required) The name of the new Resource Group. +- **groupLocation**: (required) The location of the new Resource Group. +- **azureBotId**: (required) The globally unique and immutable bot ID. Also used to configure the displayName of the bot, which is mutable. +- **azureBotSku**: The pricing tier of the Bot Service Registration. Allowed values are: F0, S1(default). +- **azureBotRegion**: Specifies the location of the new AzureBot. Allowed values are: global(default), westeurope. +- **botEndpoint**: Use to handle client messages, Such as `https://.azurewebsites.net/api/messages`. +- **appId**: (required) Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings. \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/template-AzureBot-new-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/template-AzureBot-new-rg.json new file mode 100644 index 0000000000..927307e0fc --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/template-AzureBot-new-rg.json @@ -0,0 +1,104 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "azureBotId": { + "type": "string", + "metadata": { + "description": "The globally unique and immutable bot ID." + } + }, + "azureBotSku": { + "type": "string", + "defaultValue": "S1", + "metadata": { + "description": "The pricing tier of the Bot Service Registration. Acceptable values are F0 and S1." + } + }, + "azureBotRegion": { + "type": "string", + "defaultValue": "global", + "metadata": { + "description": "" + } + }, + "botEndpoint": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Use to handle client messages, Such as https://.azurewebsites.net/api/messages." + } + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + } + }, + "variables": { + "botEndpoint": "[if(empty(parameters('botEndpoint')), concat('https://', parameters('azureBotId'), '.azurewebsites.net/api/messages'), parameters('botEndpoint'))]" + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "apiVersion": "2021-03-01", + "type": "Microsoft.BotService/botServices", + "name": "[parameters('azureBotId')]", + "location": "[parameters('azureBotRegion')]", + "kind": "azurebot", + "sku": { + "name": "[parameters('azureBotSku')]" + }, + "properties": { + "name": "[parameters('azureBotId')]", + "displayName": "[parameters('azureBotId')]", + "iconUrl": "https://docs.botframework.com/static/devportal/client/images/bot-framework-default.png", + "endpoint": "[variables('botEndpoint')]", + "msaAppId": "[parameters('appId')]", + "luisAppIds": [], + "schemaTransformationVersion": "1.3", + "isCmekEnabled": false, + "isIsolated": false + } + } + ] + } + } + } + ] +} \ No newline at end of file diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/template-BotApp-new-rg.json b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/template-BotApp-new-rg.json new file mode 100644 index 0000000000..ada32ceab9 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/deploymentTemplates/linux/deployWithNewResourceGroup/template-BotApp-new-rg.json @@ -0,0 +1,244 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "groupName": { + "type": "string", + "metadata": { + "description": "Specifies the name of the Resource Group." + } + }, + "groupLocation": { + "type": "string", + "metadata": { + "description": "Specifies the location of the Resource Group." + } + }, + "appServiceName": { + "type": "string", + "metadata": { + "description": "The globally unique name of the Web App." + } + }, + "appServicePlanName": { + "type": "string", + "metadata": { + "description": "The name of the App Service Plan." + } + }, + "appServicePlanLocation": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "The location of the App Service Plan." + } + }, + "appServicePlanSku": { + "type": "object", + "defaultValue": { + "name": "S1", + "tier": "Standard", + "size": "S1", + "family": "S", + "capacity": 1 + }, + "metadata": { + "description": "The SKU of the App Service Plan. Defaults to Standard values." + } + }, + "linuxFxVersion": { + "type": "string", + "defaultValue": "NODE|16.20" + }, + "appId": { + "type": "string", + "metadata": { + "description": "Active Directory App ID or User-Assigned Managed Identity Client ID, set as MicrosoftAppId in the Web App's Application Settings." + } + }, + "appSecret": { + "type": "string", + "metadata": { + "description": "Active Directory App Password, set as MicrosoftAppPassword in the Web App's Application Settings. Required for MultiTenant and SingleTenant app types." + } + }, + "appType": { + "defaultValue": "MultiTenant", + "type": "string", + "allowedValues": [ + "MultiTenant", + "SingleTenant", + "UserAssignedMSI" + ] + } + }, + "variables": { + "appServicePlanName": "[parameters('appServicePlanName')]", + "resourcesLocation": "[if(empty(parameters('appServicePlanLocation')), parameters('groupLocation'), parameters('appServicePlanLocation'))]", + "appServiceName": "[parameters('appServiceName')]", + "resourceGroupId": "[concat(subscription().id, '/resourceGroups/', parameters('groupName'))]" + }, + "resources": [ + { + "name": "[parameters('groupName')]", + "type": "Microsoft.Resources/resourceGroups", + "apiVersion": "2018-05-01", + "location": "[parameters('groupLocation')]", + "properties": {} + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2018-05-01", + "name": "storageDeployment", + "resourceGroup": "[parameters('groupName')]", + "dependsOn": [ + "[resourceId('Microsoft.Resources/resourceGroups/', parameters('groupName'))]" + ], + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": {}, + "resources": [ + { + "comments": "Create a new App Service Plan", + "type": "Microsoft.Web/serverfarms", + "name": "[variables('appServicePlanName')]", + "apiVersion": "2018-02-01", + "location": "[variables('resourcesLocation')]", + "sku": "[parameters('appServicePlanSku')]", + "kind": "linux", + "properties": { + "name": "[variables('appServicePlanName')]", + "perSiteScaling": false, + "reserved": true, + "targetWorkerCount": 0, + "targetWorkerSizeId": 0 + } + }, + { + "comments": "Create a Web App using the new App Service Plan", + "type": "Microsoft.Web/sites", + "apiVersion": "2015-08-01", + "name": "[parameters('appServiceName')]", + "location": "[variables('resourcesLocation')]", + "kind": "app,linux", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/serverfarms/', variables('appServicePlanName'))]" + ], + "properties": { + "enabled": true, + "hostNameSslStates": [ + { + "name": "[concat(parameters('appServiceName'), '.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Standard" + }, + { + "name": "[concat(parameters('appServiceName'), '.scm.azurewebsites.net')]", + "sslState": "Disabled", + "hostType": "Repository" + } + ], + "serverFarmId": "[variables('appServicePlanName')]", + "reserved": true, + "scmSiteAlsoStopped": false, + "clientAffinityEnabled": false, + "clientCertEnabled": false, + "hostNamesDisabled": false, + "containerSize": 0, + "dailyMemoryTimeQuota": 0, + "httpsOnly": false, + "siteConfig": { + "linuxFxVersion": "[parameters('linuxFxVersion')]", + "appSettings": [ + { + "name": "WEBSITE_NODE_DEFAULT_VERSION", + "value": "16.20.2" + }, + { + "name": "MicrosoftAppType", + "value": "[parameters('appType')]" + }, + { + "name": "MicrosoftAppId", + "value": "[parameters('appId')]" + }, + { + "name": "MicrosoftAppPassword", + "value": "[parameters('appSecret')]" + } + ] + } + } + }, + { + "type": "Microsoft.Web/sites/config", + "apiVersion": "2016-08-01", + "name": "[concat(parameters('appServiceName'), '/web')]", + "location": "[variables('resourcesLocation')]", + "dependsOn": [ + "[concat(variables('resourceGroupId'), '/providers/Microsoft.Web/sites/', parameters('appServiceName'))]" + ], + "properties": { + "numberOfWorkers": 1, + "defaultDocuments": [ + "Default.htm", + "Default.html", + "Default.asp", + "index.htm", + "index.html", + "iisstart.htm", + "default.aspx", + "index.php", + "hostingstart.html" + ], + "netFrameworkVersion": "v4.0", + "phpVersion": "", + "pythonVersion": "", + "nodeVersion": "", + "linuxFxVersion": "[parameters('linuxFxVersion')]", + "requestTracingEnabled": false, + "remoteDebuggingEnabled": false, + "httpLoggingEnabled": true, + "logsDirectorySizeLimit": 35, + "detailedErrorLoggingEnabled": false, + "publishingUsername": "[concat('$', parameters('appServiceName'))]", + "scmType": "LocalGit", + "use32BitWorkerProcess": true, + "webSocketsEnabled": false, + "alwaysOn": true, + "appCommandLine": "", + "managedPipelineMode": "Integrated", + "virtualApplications": [ + { + "virtualPath": "/", + "physicalPath": "site\\wwwroot", + "preloadEnabled": true, + "virtualDirectories": null + } + ], + "winAuthAdminState": 0, + "winAuthTenantState": 0, + "customAppPoolIdentityAdminState": false, + "customAppPoolIdentityTenantState": false, + "loadBalancing": "LeastRequests", + "routingRules": [], + "experiments": { + "rampUpRules": [] + }, + "autoHealEnabled": false, + "vnetName": "", + "minTlsVersion": "1.2", + "ftpsState": "AllAllowed", + "reservedInstanceCount": 0 + } + } + ] + } + } + } + ] +} diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/index.js b/samples/javascript_nodejs/85.bot-authentication-sni/index.js new file mode 100644 index 0000000000..785b23805f --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/index.js @@ -0,0 +1,132 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +const path = require('path'); +// const fs = require('fs'); +const dotenv = require('dotenv'); +const restify = require('restify'); +const msal = require('@azure/msal-node'); +const { DefaultAzureCredential } = require('@azure/identity'); +const { SecretClient } = require('@azure/keyvault-secrets'); +const { MsalServiceClientCredentialsFactory } = require('botframework-connector'); + +// Import required bot configuration. +const ENV_FILE = path.join(__dirname, '.env'); +dotenv.config({ path: ENV_FILE }); + +// Import required bot services. +// See https://aka.ms/bot-services to learn more about the different parts of a bot. +const { + CloudAdapter, + ConfigurationBotFrameworkAuthentication +} = require('botbuilder'); + +// This bot's main dialog. +const { AuthBot } = require('./authBot'); + +(async () => { + try { + // Create HTTP server. + const server = restify.createServer(); + server.use(restify.plugins.bodyParser()); + + server.listen(process.env.port || process.env.PORT || 3978, () => { + console.log(`\n${ server.name } listening to ${ server.url }`); + console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator'); + console.log('\nTo talk to your bot, open the emulator select "Open Bot"'); + }); + + const authorityUrl = 'https://login.microsoftonline.com/botframework.com'; + + // ---- Authenticate using key vault to obtain the certificate values. + // Create an Azure credential to authenticate. + const credential = new DefaultAzureCredential(); + + const vaultName = process.env.KeyVaultName; + const keyVaultUrl = `https://${ vaultName }.vault.azure.net`; + + const certificateName = process.env.CertificateName; + + // Using an Azure credential object and a keyVaultUrl, let's create a SecretClient. + const secretClient = new SecretClient(keyVaultUrl, credential); + + // Assuming you've already created a Key Vault certificate, + // and that certificateName contains the name of your certificate. + const certificateSecret = await secretClient.getSecret(certificateName); + + // Here we can find both the private key and the public certificate, in PKCS 12 format: + const certificateKey = certificateSecret.value; + + // ---- Authenticate using local certificate. + // const key = fs.readFileSync('{KeyPath}.pem', 'utf8'); + + // Extract x5c value from the key string to use the SNI authentication. + const x5cValue = certificateKey.split('-----BEGIN CERTIFICATE-----\n').pop().split('\n-----END CERTIFICATE-----')[0]; + + // Create client credentials using SNI authentication from MSAL. + const serviceClientCredentialsFactory = new MsalServiceClientCredentialsFactory( + process.env.MicrosoftAppId, + new msal.ConfidentialClientApplication({ + auth: { + clientId: process.env.MicrosoftAppId, + authority: authorityUrl, + clientCertificate: { + thumbprint: process.env.CertificateThumbprint, + privateKey: certificateKey, + x5c: x5cValue + } + } + }) + ); + + const botFrameworkAuthentication = new ConfigurationBotFrameworkAuthentication(process.env, serviceClientCredentialsFactory); + + // Create adapter. + // See https://aka.ms/about-bot-adapter to learn more about how bots work. + const adapter = new CloudAdapter(botFrameworkAuthentication); + // Catch-all for errors. + const onTurnErrorHandler = async (context, error) => { + // This check writes out errors to console log .vs. app insights. + // NOTE: In production environment, you should consider logging this to Azure + // application insights. See https://aka.ms/bottelemetry for telemetry + // configuration instructions. + console.error(`\n [onTurnError] unhandled error: ${ error }`); + + // Send a trace activity, which will be displayed in Bot Framework Emulator + await context.sendTraceActivity( + 'OnTurnError Trace', + `${ error }`, + 'https://www.botframework.com/schemas/error', + 'TurnError' + ); + + // Send a message to the user + await context.sendActivity('The bot encountered an error or bug.'); + await context.sendActivity('To continue to run this bot, please fix the bot source code.'); + }; + + // Set the onTurnError for the singleton CloudAdapter. + adapter.onTurnError = onTurnErrorHandler; + + // Create the main dialog. + const myBot = new AuthBot(); + + // Listen for incoming requests. + server.post('/api/messages', async (req, res) => { + // Route received a request to adapter for processing + await adapter.process(req, res, (context) => myBot.run(context)); + }); + + // Listen for Upgrade requests for Streaming. + server.on('upgrade', async (req, socket, head) => { + // Create an adapter scoped to this WebSocket connection to allow storing session data. + const streamingAdapter = new CloudAdapter(botFrameworkAuthentication); + // Set onTurnError for the CloudAdapter created for each connection. + streamingAdapter.onTurnError = onTurnErrorHandler; + + await streamingAdapter.process(req, socket, head, (context) => myBot.run(context)); + }); + } catch (error) { + console.log(error); + } +})(); diff --git a/samples/javascript_nodejs/85.bot-authentication-sni/package.json b/samples/javascript_nodejs/85.bot-authentication-sni/package.json new file mode 100644 index 0000000000..a9778907a1 --- /dev/null +++ b/samples/javascript_nodejs/85.bot-authentication-sni/package.json @@ -0,0 +1,35 @@ +{ + "name": "bot-authentication-sni", + "version": "1.0.0", + "description": "Bot Builder v4 bot authentication with subject name/issuer sample", + "author": "Microsoft", + "license": "MIT", + "main": "index.js", + "scripts": { + "start": "node ./index.js", + "watch": "nodemon ./index.js", + "lint": "eslint .", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com" + }, + "dependencies": { + "@azure/identity": "^3.3.0", + "@azure/keyvault-certificates": "^4.7.0", + "@azure/keyvault-secrets": "^4.7.0", + "botbuilder": "^4.21.0", + "dotenv": "^8.2.0", + "restify": "~8.6.0" + }, + "devDependencies": { + "eslint": "^7.0.0", + "eslint-config-standard": "^14.1.1", + "eslint-plugin-import": "^2.20.2", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-standard": "^4.0.1", + "nodemon": "~2.0.4" + } +}