Private Endpoint and Direct Line App Service Extension Configuration to Azure App Service and Azure Bot Service.
We must follow below article to configure Direct Line App Service Extension to App Service and Azure Bot Service:
Direct Line App Service extension - Bot Service | Microsoft Learn
First, let's create a simple Azure Bot Service and Azure App service, deploy the Bot sample code(Echo-Bot for .NET Core) and get everything working.
Note: All the resources must be in the same region and under same resource group.
Please follow the steps below to create and configure Bot Service and App Service.
Create an App Service:
Here I am creating a new resource group (directlineextension-RG) which we will use for all other resources we will create.
Create a Bot Service:
Update the Messaging Endpoint of Bot:
Here in my case URL is "https://directlineextension.azurewebsites.net"
Download the sample Bot code from below GitHub repository:
I am going to use Echo-Bot sample for .NET Core.
Open the code in your editor (I am using VS code) and update below 4 property values available at appsettings.json file:
{
"MicrosoftAppType": "",
"MicrosoftAppId": "",
"MicrosoftAppPassword": "",
"MicrosoftAppTenantId": ""
}
Please follow below steps to get the values for above properties:
Copy Bot Type as value for "MicrosoftAppType"
Generate a new secret and copy the value
Save appsettings.json file and deploy the code to App Service.
Once code is deployed successfully to App Service, test the Bot using "Test in Web Chat".
If everything is working as expected then we are good to go to next step.
We will follow below article to configure .NET bot for extension:
If your requirement is to use Nodejs bot then you must follow below document to configure Nodejs bot for extension:
We have fullfilled the prerequirsites.
This section describes how to enable the Direct Line App Service extension using the App Service extension key from your bot's Direct Line channel configuration.
Note
The Microsoft.Bot.Builder.StreamingExtensions NuGet preview packages have been deprecated. Starting with v4.8, the SDK contains a Microsoft.Bot.Builder.Streaming
namespace. If a bot previously made use of the preview packages, they must be removed before following the steps below.
Open the Startup.cs file.
using Microsoft.Bot.Builder.Integration.AspNet.Core;
UseNamedPipes
method as below:public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseDefaultFiles()
.UseStaticFiles()
.UseWebSockets()
// Allow the bot to use named pipes.
.UseNamedPipes(System.Environment.GetEnvironmentVariable("APPSETTING_WEBSITE_SITE_NAME") + ".directline")
.UseRouting()
.UseAuthorization()
.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// app.UseHttpsRedirection();
}
Save the Startup.cs file.
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>latest</LangVersion>
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
</PropertyGroup>
In the Settings section, select the Configuration menu item, add below "New application setting"
Name | Value |
---|---|
DirectLineExtensionKey | The value of the App Service extension key you copied earlier. |
DIRECTLINE_EXTENSION_VERSION | latest |
Select Save to save the settings. This restarts the Azure App Service.
In your browser, go to https://<your_app_service>.azurewebsites.net/.bot
. If everything is correct, the page will return the following JSON content:
{"v":"123","k":true,"ib":true,"ob":true,"initialized":true}
If the ib and ob values displayed by the .bot endpoint are false, the bot and the Direct Line App Service extension are unable to connect to each other.
If the initialized value of the .bot endpoint is false, the Direct Line App Service extension is unable to validate the App Service extension key added to the bot's Application Settings above.
Enable the bot to use the out of process hosting model; otherwise, you'll receive an HTTP Error 500.34 - ANCM Mixed Hosting error (where ANCM stands for ASP.NET Core Module). This error occurs because the bot template is using the InProcess
hosting model by default. To configure out of process hosting, see Out-of-process hosting model. For more information, see Attributes of the aspNetCore element and Configuration with web.config.
ClaimsIdentity
to AudienceClaim
on the BotFrameworkHttpAdapter
. To do so, you can subclass the adapter. For example:
public class AdapterWithStaticClaimsIdentity : BotFrameworkHttpAdapter
{
public AdapterWithStaticClaimsIdentity(IConfiguration configuration, ILogger<BotFrameworkHttpAdapter> logger, ConversationState conversationState = null)
: base(configuration, logger)
{
// Manually create the ClaimsIdentity and create a Claim with a valid AudienceClaim and the AppID for a bot using the Direct Line App Service extension.
var appId = configuration.GetSection(MicrosoftAppCredentials.MicrosoftAppIdKey)?.Value;
ClaimsIdentity = new ClaimsIdentity(new List<Claim>{
new Claim(AuthenticationConstants.AudienceClaim, appId)
});
}
}
If everything works as expected till this point then we are good to proceed to next step.
You can add network isolation to an existing Direct Line App Service extension bot. A private endpoint lets your network isolated bot communicate with required Bot Framework services so that the bot can run correctly while being limited to the virtual network.
To add network isolation to your bot:
To confirm that your existing bot is configured correctly:
https://<your-app_service>.azurewebsites.net/.bot
{"v":"123","k":true,"ib":true,"ob":true,"initialized":true}
Resource Group: directlineextension-RG
Open the app service resource for your bot and enable virtual network integration.
Use the virtual network and subnet from the previous step.
In a separate browser tab, open the Direct Line client endpoint for your bot. For example, https://<your-app_service>.azurewebsites.net/.bot
.
{"v":"123","k":true,"ib":true,"ob":true,"initialized":false}
The value of initialized
should be false
, because your app service and app service extension are unable to connect to other Bot Framework services to initialize itself. Your bot is now isolated in a virtual network for outbound connections.
Keep the rest settings default and Review + Create.
DirectLineExtensionABSEndpoint
.https://<your_azure_bot>.privatelink.directline.botframework.com/v3/extension
.<your_azure_bot>
with your Bot Name.Restart the app service for your bot.
https://<your-app_service>.azurewebsites.net/.bot
{"v":"123","k":true,"ib":true,"ob":true,"initialized":true}
The value of initialized
should be true
.
If your private endpoint doesn't work correctly, you can add a rule to allow outbound traffic to NSG configured with the App Service subnet (subnet-appservice) specifically to Azure Bot Service.
This will make you virtual network a little less isolated.
In a separate browser tab, open the Direct Line client endpoint for your bot again. For example, https://<your-app_service>.azurewebsites.net/.bot
.
{"v":"123","k":true,"ib":true,"ob":true,"initialized":true}
Now add Private Endpoint to App Service:
If you try to browse the App Service URL and the Pipe URL, you will not get any response.
Now, lets create a client to test the Bot. We will use below article to get the required HTML and replace the required values:
Copy the provided HTML:
Replace <your_app_service> with your App Service name in 2 places hightlighed in the HTML above.
Replace <Your Bot's Direct Line channel secret> with the Direct line channel secret (the secret is used only for testing purposes, and not meant to be placed inside the client for production uses):
Now run the client in the machine, which is part of the same vnet, configured here as part of the private endpoint.
For testing purpose, we will create a Virtual Machine and configure this VM to be part of same vnet which is configured with App Service and Bot Service.
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Web Chat</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script
crossorigin="anonymous"
src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"
></script>
<style>
html,
body {
background-color: #f7f7f7;
height: 100%;
}
body {
margin: 0;
}
#webchat {
box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);
height: 100%;
margin: auto;
max-width: 480px;
min-width: 360px;
}
</style>
</head>
<body>
<div id="webchat" role="main"></div>
<script>
(async function() {
<!-- NOTE: You should replace the below fetch with a call to your own token service as described in step 2 above, to avoid exposing your channel secret in client side code. -->
const res = await fetch('https://<your_app_service>.azurewebsites.net/.bot/v3/directline/tokens/generate',
{
"method": "POST",
"headers": {
"Authorization": "Bearer " + "<Your Bot's Direct Line channel secret>"
},
"body": "{'user': {'id': 'my_test_id', 'name': 'my_test_name'}}"
}
);
const { token } = await res.json();
window.WebChat.renderWebChat(
{
directLine: await window.WebChat.createDirectLineAppServiceExtension({
domain: 'https://<your_app_service>.azurewebsites.net/.bot/v3/directline',
token
})
},
document.getElementById('webchat')
);
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
</script>
</body>
</html>
In the networking section, configure the same vnet and subnet (subnet-vm) we have created earlier for VM.
Once VM is created successfully, login to VM and take the client HTML created earlier and run inside the VM.
It must work without any issue and you must see the expected response from the Bot.
You must be able to use pipe URL too, inside the VM:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.