Skip to content

Commit

Permalink
Using CertificateServiceClientCredentialsFactory for SN+I sample
Browse files Browse the repository at this point in the history
  • Loading branch information
Tracy Boehrer committed Jun 18, 2024
1 parent 1330610 commit 9b61736
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Identity" Version="1.10.2" />
<PackageReference Include="Azure.Identity" Version="1.11.4" />
<PackageReference Include="Azure.Security.KeyVault.Certificates" Version="4.5.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.7" />
<PackageReference Include="Microsoft.Bot.Builder.Dialogs" Version="4.22.3" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@ namespace Microsoft.BotBuilderSamples
{
public class AuthSNIBot : ActivityHandler
{
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var replyText = $"Echo: {turnContext.Activity.Text}";
await turnContext.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken);
}

protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
foreach (var member in turnContext.Activity.MembersAdded)
var welcomeText = "Hello and welcome!";
foreach (var member in membersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
await turnContext.SendActivityAsync(MessageFactory.Text("Welcome to the Bot with Subject Name/Issuer Authentication."), cancellationToken);
await turnContext.SendActivityAsync(MessageFactory.Text(welcomeText, welcomeText), cancellationToken);
}
}
}

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var replyText = "Running dialog with bot authenticated";
await turnContext.SendActivityAsync(MessageFactory.Text(replyText, replyText), cancellationToken);
}
}
}

This file was deleted.

97 changes: 31 additions & 66 deletions samples/csharp_dotnetcore/85.bot-authentication-sni/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,91 +21,56 @@ This bot has been created using [Bot Framework](https://dev.botframework.com/),
git clone https://github.com/microsoft/botbuilder-samples.git
```

- Set app settings variables

- MicrosoftAppType: Type of the App.

- MicrosoftAppId: App Id of your bot.

- MicrosoftAppTenantId: Tenant Id to which your bot belongs.

- KeyVaultName: Name of the KeyVault containing the certificate.

- CertificateName: Name of the certificate in the KeyVault.


- Run the bot from a terminal or from Visual Studio:

A) From a terminal, navigate to `samples/csharp_dotnetcore/85.bot-authentication-sni`

```bash
# run the bot
dotnet run
```

B) Or from Visual Studio

- Open from Visual Studio
- Launch Visual Studio
- File -> Open -> Project/Solution
- Navigate to `samples/csharp_dotnetcore/85.bot-authentication-sni` folder
- Select `AuthSNIBot.csproj` file
- Press `F5` to run the project

## Testing the bot using Bot Framework Emulator
- Create an SSL/TLS certificate using KeyVault
1. Create a KeyVault resource and assign _the KeyVault Administrator_ role to have permission to create a new certificate.

[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.
2. Under the Certificates section, hit on Generate/Import, complete the form, and create the certificate in PEM format.

- Install the latest Bot Framework Emulator from [here](https://github.com/Microsoft/BotFramework-Emulator/releases)
3. Go to the details of the certificate that you created and enable it and record the subject name

### Connect to the bot using Bot Framework Emulator
- Create Azure App and Bot
- Create App Registration
- This can be either Single or Multi tenant
- Record the Application ID
- Add this to the Manifest
"trustedCertificateSubjects": [
{
"authorityId": "00000000-0000-0000-0000-000000000001",

"subjectName": "certificate_subject_name",

"revokedCertificateIdentifiers": []
}
]
- Create an Azure Bot in the desired resource group. Use the App Registration from the previous step.

- Launch Bot Framework Emulator
- File -> Open Bot
- Enter a Bot URL of `http://localhost:3978/api/messages`
- Set appsettings.json variables

## Interacting with the bot
- MicrosoftAppType: {SingTenant | MultiTenant}

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.
- MicrosoftAppId: {appId}

## SSL/TLS certificate
- MicrosoftAppTenantId: {tenantId}

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 "<directory-to-store-certificate>" -Subject "CN=<certificate-name>" -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 <certificate-name>.pfx -out c:\<certificate-name>.pem –nodes
```
- KeyVaultName: Name of the KeyVault containing the certificate.

5. Upload the generated certificate to the Azure app registration.
- CertificateName: Name of the certificate in the KeyVault.

### Using KeyVault
- Run the bot from Visual Studio:

1. Create a KeyVault resource and assign _the KeyVault Administrator_ role to have permission to create a new certificate.
## Interacting with the bot

2. Under the Certificates section, hit on Generate/Import, complete the form, and create the certificate in PEM format.
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.

3. Go to the details of the certificate that you created and enable it.
## SSL/TLS certificate

4. Download the certificate in CER format and then upload it to the Azure app registration.
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.

## Deploy the bot to Azure

Expand Down
37 changes: 13 additions & 24 deletions samples/csharp_dotnetcore/85.bot-authentication-sni/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@ public void ConfigureServices(IServiceCollection services)
options.SerializerSettings.MaxDepth = HttpHelper.BotMessageSerializerSettings.MaxDepth;
});

//Set sendX5C value to true to use SNI auhtentication.

//
// NOTE
//
// This is a provisional sample for SN+I. It is likely to change in the future as this
// functionality is rolled into BF SDK.
//

// Set sendX5C value to true to use SNI authentication.
var sendX5C = true;

// Using KeyVault.
Expand All @@ -43,37 +51,20 @@ public void ConfigureServices(IServiceCollection services)
var credential = new DefaultAzureCredential();
var client = new CertificateClient(new Uri(keyVaultUri), credential);

//Get certificate in X509Certificate format.
// Get certificate in X509Certificate format.
var certificateName = _configuration["CertificateName"];
var certificate = client.DownloadCertificate(certificateName).Value;

// Using a local certificate.
//var certificate = X509Certificate2.CreateFromPemFile(@"{Pem file path}");

// MSAL certificate auth.
services.AddSingleton(
serviceProvider => ConfidentialClientApplicationBuilder.Create(_configuration["MicrosoftAppId"])
.WithCertificate(certificate, sendX5C)
.Build());

// MSAL credential factory: regardless of secret, cert or custom auth, need to add the line below to enable MSAL.
services.AddSingleton<ServiceClientCredentialsFactory, MsalServiceClientCredentialsFactory>();
// Register CertificateServiceClientCredentialsFactory
services.AddSingleton<ServiceClientCredentialsFactory>(
new CertificateServiceClientCredentialsFactory(certificate, _configuration["MicrosoftAppId"], _configuration["MicrosoftAppTenantId"], null, null, sendX5C));

// Create the Bot Framework Authentication to be used with the Bot Adapter.
services.AddSingleton<BotFrameworkAuthentication, ConfigurationBotFrameworkAuthentication>();

// Create the Bot Adapter with error handling enabled.
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();

// Create the storage we'll be using for User and Conversation state. (Memory is great for testing purposes.)
services.AddSingleton<IStorage, MemoryStorage>();

// Create the User state. (Used in this bot's Dialog implementation.)
services.AddSingleton<UserState>();

// Create the Conversation state. (Used by the Dialog system itself.)
services.AddSingleton<ConversationState>();

// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, AuthSNIBot>();
}
Expand All @@ -93,8 +84,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
endpoints.MapControllers();
});

// app.UseHttpsRedirection();
}
}
}

0 comments on commit 9b61736

Please sign in to comment.