diff --git a/samples/csharp_dotnetcore/18.bot-authentication/AuthenticationBot.csproj b/samples/csharp_dotnetcore/18.bot-authentication/AuthenticationBot.csproj index c6c4b0cc70..b2edfcf3a3 100644 --- a/samples/csharp_dotnetcore/18.bot-authentication/AuthenticationBot.csproj +++ b/samples/csharp_dotnetcore/18.bot-authentication/AuthenticationBot.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/samples/csharp_dotnetcore/18.bot-authentication/README.md b/samples/csharp_dotnetcore/18.bot-authentication/README.md index bc3c81d681..d7b72873c8 100644 --- a/samples/csharp_dotnetcore/18.bot-authentication/README.md +++ b/samples/csharp_dotnetcore/18.bot-authentication/README.md @@ -1,6 +1,6 @@ # Bot Authentication -Bot Framework v4 bot authentication sample +Bot Framework v4 bot authentication sample. This bot has been created using [Bot Framework](https://dev.botframework.com), it shows how to use authentication in your bot using OAuth. @@ -8,6 +8,8 @@ The sample uses the bot authentication capabilities in [Azure Bot Service](https NOTE: Microsoft Teams currently differs slightly in the way auth is integrated with the bot. Refer to sample 5 [here](https://github.com/OfficeDev/Microsoft-Teams-Samples#bots-samples-using-the-v4-sdk). +NOTE: This sample has been updated to use Federated Identity Credentials (FIC), but it also supports ClientSecret authentication following this guide: [Add Authentication to your bot via Azure Bot Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp). + ## Prerequisites - [.NET SDK](https://dotnet.microsoft.com/download) version 8.0 @@ -17,6 +19,8 @@ NOTE: Microsoft Teams currently differs slightly in the way auth is integrated w dotnet --version ``` +- [Bot Framework SDK](https://github.com/microsoft/botbuilder-dotnet/releases) version 4.22.8 onwards + ## To try this sample - Clone the repository @@ -25,67 +29,84 @@ NOTE: Microsoft Teams currently differs slightly in the way auth is integrated w git clone https://github.com/microsoft/botbuilder-samples.git ``` -- Deploy your bot to Azure, see [Deploy your bot to Azure](https://aka.ms/azuredeployment) - -- [Add Authentication to your bot via Azure Bot Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp) - -After Authentication has been configured via Azure Bot Service, you can test the bot. - -- Update `appsettings.json` with required configuration settings - | Property | Value Description | - |----------------------|-----------| - | MicrosoftAppId | Set the value of your Azure bot's app ID. | - | MicrosoftAppPassword | Set the Azure Active Directory app client secret value. | - | ConnectionName | Set the configured bot's OAuth connection name. | +- Create a MS Entra ID application to register a bot resource in Azure and a separate MS Entra ID application to function as the identity provider. + + - Create a User Assigned Managed Identity + - Record the client ID of the managed identity. + - Create an App Service + - Add the User managed identity created in previous step to the Azure App Service under Configuration -> Identity -> User Assigned Managed Identity. + - Record the **Default domain** on the **Overview** tab. + - Create App Registration + - This should be Single tenant (Currently, FIC feature is supported in single tenant bots only). + - Record the Application and Tenant ID's. + - To create trust using the FIC, we need to link the managed identity to the App Registration. On the App Registration: + - Click on the add credential under **Certificates & Secrets**, **Federated credentials**. + - On the Add a credential page, select the Federated credential scenario as **Managed Identity**. + - Select the managed identity that you created in the previous step. + - Enter name for the credential and click on **Add**. + - Create an **Azure Bot** in the desired resource group and use the App Registration from the previous step + - Update the **Messaging endpoint** on the **Configuration** tab to: https://{default-domain}/api/messages. + - Create the **Identity Provider** + - Create the AppRegistration + - Select SingleTenant and for the Redirect URL, use one of the followings: [OAuth URL support in Azure AI Bot Service](https://learn.microsoft.com/en-us/azure/bot-service/ref-oauth-redirect-urls?view=azure-bot-service-4.0). + - Record the Application and Tenant ID's. + - Click on the add credential under **Certificates & Secrets**, **Federated credentials**. + - On the Add a credential page, select the Federated credential scenario as **Other Issuer**. + - Provide information under **Connect your account** section: + - Issuer: "https://login.microsoftonline.com/{tenant-ID}/v2.0" + - Subject Identifier: "/eid1/c/pub/t/{base64-encoded-tenant-ID}/a/{base64-encoded-first-party-app-client-ID}/{unique-identifier-for-projected-identity}" + - Audience: api://AzureADTokenExchange + - Unique-identifier-for-projected-identity: Set a unique identifier + + NOTE: You can encode the tenant ID using [this code](https://dotnetfiddle.net/p11CFZ), and for the encoded first-party-app-client-ID, you can use one of these values: `9ExAW52n_ky4ZiS_jhpJIQ`, `ND1y8_Vv60yhSNmdzSUR_A`. + + - In the **API Permisions** tab, grant the following permisions: openid, profile, Mail.Read, Mail.Send, User.Read, User.ReadBasic.All. + - Register the Identity Provider with the bot + - Add an **OAuth Connection Settings** in your **Azure Bot** resource, on the **Configuration** tab. + - Service Provider: AAD v2 with Federated Credentials + - Client ID: The App Registration ID of the identity provider created in the previous step + - Unique Identifier: The unique identifier of the identity provider created in the previous step + - Token Exchange URL: leave it blank + - Login URL: leave it blank + - Tenant ID: The Tenant ID of the identity provider created in the previous step + - Scopes: The names of the permissions from the application registration + - Test the connection and concent the requested permissions. + +- After Authentication has been configured via Azure Bot Service, you can test the bot. + + - Update `appsettings.json` with required configuration settings: + | Property | Value Description | + |----------------------|-----------| + | MicrosoftAppType | SingleTenant | Currently, FIC feature is supported in single tenant bots only. | + | MicrosoftAppId | The bot's app ID. | + | MicrosoftAppTenantId | The bot's app tenant ID. | + | MicrosoftAppClientId | The User Managed Identity ID. | + | ConnectionName | The configured bot's OAuth connection name. | -- Run the bot from a terminal or from Visual Studio: - - A) From a terminal, navigate to `samples/csharp_dotnetcore/18.bot-authentication` - - ```bash - # run the bot - dotnet run - ``` + - A bot using Federated Credentials, like UserManagedIdentity, cannot be run locally. It must be deployed to Azure. - B) Or from Visual Studio - - - Launch Visual Studio - - File -> Open -> Project/Solution - - Navigate to `samples/csharp_dotnetcore/18.bot-authentication` folder - - Select `AuthenticationBot.csproj` file - - Press `F5` to run the project - -## 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) +## Deploy the bot to Azure -### Connect to the bot using Bot Framework Emulator +The easiest way to deploy the bot to the App Service for testing is using the Visual Studio **Publish** tool. +- Right click the project and select **Publish**. +- Click **+ New Profile**. +- **Azure** -> **Azure App Service (Windows)**. +- Select the existing App Service, then click **Finish**. +- Click the **Publish** button. -- Launch Bot Framework Emulator -- File -> Open Bot -- Enter a Bot URL of `http://localhost:3978/api/messages` ## Interacting with the bot This sample uses bot authentication capabilities in Azure Bot Service, providing features to make it easier to develop a bot that authenticates users to various identity providers such as Azure AD (Azure Active Directory), GitHub, Uber, etc. These updates also take steps towards an improved user experience by eliminating the magic code verification for some clients. -## 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) - [Azure Portal](https://portal.azure.com) - [Add Authentication to Your Bot Via Azure Bot Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-authentication?view=azure-bot-service-4.0&tabs=csharp) +- [Implement Authentication with Federated Identity Credentials](https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-authentication-federated-credential?view=azure-bot-service-4.0&tabs=csharp) - [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) -- [.NET Core CLI tools](https://docs.microsoft.com/en-us/dotnet/core/tools/?tabs=netcore2x) -- [Azure CLI](https://docs.microsoft.com/cli/azure/?view=azure-cli-latest) -- [Azure Portal](https://portal.azure.com) -- [Language Understanding using LUIS](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/) - [Channels and Bot Connector Service](https://docs.microsoft.com/en-us/azure/bot-service/bot-concepts?view=azure-bot-service-4.0) diff --git a/samples/csharp_dotnetcore/18.bot-authentication/Startup.cs b/samples/csharp_dotnetcore/18.bot-authentication/Startup.cs index d5d50ccb82..98dc00961f 100644 --- a/samples/csharp_dotnetcore/18.bot-authentication/Startup.cs +++ b/samples/csharp_dotnetcore/18.bot-authentication/Startup.cs @@ -6,6 +6,7 @@ using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Connector.Authentication; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -13,6 +14,13 @@ namespace Microsoft.BotBuilderSamples { public class Startup { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { @@ -21,6 +29,13 @@ public void ConfigureServices(IServiceCollection services) options.SerializerSettings.MaxDepth = HttpHelper.BotMessageSerializerSettings.MaxDepth; }); + // Create the Federated Service Client Credentials to be used as the ServiceClientCredentials for the Bot Framework SDK. + services.AddSingleton( + new FederatedServiceClientCredentialsFactory( + Configuration["MicrosoftAppId"], + Configuration["MicrosoftAppClientId"], + Configuration["MicrosoftAppTenantId"])); + // Create the Bot Framework Authentication to be used with the Bot Adapter. services.AddSingleton(); diff --git a/samples/csharp_dotnetcore/18.bot-authentication/appsettings.json b/samples/csharp_dotnetcore/18.bot-authentication/appsettings.json index 82a6cbc6d1..69509126eb 100644 --- a/samples/csharp_dotnetcore/18.bot-authentication/appsettings.json +++ b/samples/csharp_dotnetcore/18.bot-authentication/appsettings.json @@ -1,7 +1,7 @@ { "MicrosoftAppType": "", "MicrosoftAppId": "", - "MicrosoftAppPassword": "", + "MicrosoftAppClientId": "", "MicrosoftAppTenantId": "", "ConnectionName": "" } diff --git a/samples/csharp_dotnetcore/86.bot-authentication-fic/AdapterWithErrorHandler.cs b/samples/csharp_dotnetcore/86.bot-authentication-fic/AdapterWithErrorHandler.cs index 6761e30a1d..322a6d3790 100644 --- a/samples/csharp_dotnetcore/86.bot-authentication-fic/AdapterWithErrorHandler.cs +++ b/samples/csharp_dotnetcore/86.bot-authentication-fic/AdapterWithErrorHandler.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -using System; -using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.TraceExtensions; using Microsoft.Bot.Connector.Authentication; @@ -12,7 +10,7 @@ namespace Microsoft.BotBuilderSamples { public class AdapterWithErrorHandler : CloudAdapter { - public AdapterWithErrorHandler(BotFrameworkAuthentication auth, ILogger logger, ConversationState conversationState = default) + public AdapterWithErrorHandler(BotFrameworkAuthentication auth, ILogger logger) : base(auth, logger) { OnTurnError = async (turnContext, exception) => @@ -27,21 +25,6 @@ public AdapterWithErrorHandler(BotFrameworkAuthentication auth, ILogger - net6.0 + net8.0 latest - + diff --git a/samples/csharp_dotnetcore/86.bot-authentication-fic/Controllers/BotController.cs b/samples/csharp_dotnetcore/86.bot-authentication-fic/Controllers/BotController.cs index ba57b68f80..77c1cf35b5 100644 --- a/samples/csharp_dotnetcore/86.bot-authentication-fic/Controllers/BotController.cs +++ b/samples/csharp_dotnetcore/86.bot-authentication-fic/Controllers/BotController.cs @@ -5,7 +5,7 @@ using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Integration.AspNet.Core; -namespace bot_authentication_fic.Controllers +namespace Microsoft.BotBuilderSamples.Controllers { // This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot // implementation at runtime. Multiple different IBot implementations running at different endpoints can be diff --git a/samples/csharp_dotnetcore/86.bot-authentication-fic/README.md b/samples/csharp_dotnetcore/86.bot-authentication-fic/README.md index 28cc0ed631..c740dda0c6 100644 --- a/samples/csharp_dotnetcore/86.bot-authentication-fic/README.md +++ b/samples/csharp_dotnetcore/86.bot-authentication-fic/README.md @@ -1,8 +1,8 @@ -# Bot using Federation Identity Credentials +# Bot using Federated Identity Credentials -Bot Framework v4 bot authentication using Federation Identity Credentials (FIC). Currently, FIC feature is supported single tenant bots only. +Bot Framework v4 bot authentication using Federated Identity Credentials (FIC). Currently, FIC feature is supported in single tenant bots only. -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 federated identity certificate configuration to create the Bot Framework Authentication. +This bot has been created using [Bot Framework](https://dev.botframework.com/), it shows how to use the bot authentication capabilities of Azure Bot Service. In this sample, we use federated identity credentials configuration to create the Bot Framework Authentication. This bot uses `FederatedServiceClientCredentialsFactory` which is registered in Startup.cs. @@ -38,11 +38,11 @@ This bot uses `FederatedServiceClientCredentialsFactory` which is registered in - Record the **Default domain** on the **Overview** tab - Create Azure App and Bot - Create App Registration - - This can be either Single or Multi tenant. + - This should be Single tenant (Currently, FIC feature is supported in single tenant bots only). - Record the Application and Tenant ID's. - - To create trust using the FIC, we need to link the managed identity to the App Registration. On the App Registration: + - To create trust using the FIC, we need to link the managed identity to the App Registration. On the App Registration: - Click on the add credential under **Certificates & Secrets**, **Federated credentials** - - On the Add a credential page, select the Federated credential scenario as **Customer Managed Keys**. + - On the Add a credential page, select the Federated credential scenario as **Managed Identity**. - Select the managed identity that you created in the previous step. - Enter name for the credential and click on **Add**. @@ -51,9 +51,9 @@ This bot uses `FederatedServiceClientCredentialsFactory` which is registered in - For an existing bot - Navigate to the **App Registration** for the **Azure Bot** - - To create trust using the FIC, we need to link the managed identity to the App Registration. On the App Registration: + - To create trust using the FIC, we need to link the managed identity to the App Registration. On the App Registration: - Click on the add credential under **Certificates & Secrets**, **Federated credentials** - - On the Add a credential page, select the Federated credential scenario as **Customer Managed Keys**. + - On the Add a credential page, select the Federated credential scenario as **Managed Identity**. - Select the managed identity that you created in the previous step. - Enter name for the credential and click on **Add**. - Navigate to the **App Service** for the bot @@ -61,7 +61,7 @@ This bot uses `FederatedServiceClientCredentialsFactory` which is registered in - Set appsettings.json variables - - MicrosoftAppType: SingTenant + - MicrosoftAppType: SingleTenant - MicrosoftAppId: {bot-appId} @@ -69,7 +69,7 @@ This bot uses `FederatedServiceClientCredentialsFactory` which is registered in - MicrosoftAppClientId: {clientId of managed identity} -- A bot using Federated Credentials, like UserManagedIdentity, cannot be run locally. It must be deployed to Azure. +- A bot using Federated Credentials, like UserManagedIdentity, cannot be run locally. It must be deployed to Azure. ## Deploy the bot to Azure diff --git a/samples/csharp_dotnetcore/86.bot-authentication-fic/Startup.cs b/samples/csharp_dotnetcore/86.bot-authentication-fic/Startup.cs index a4f40438d0..5be655e0cc 100644 --- a/samples/csharp_dotnetcore/86.bot-authentication-fic/Startup.cs +++ b/samples/csharp_dotnetcore/86.bot-authentication-fic/Startup.cs @@ -42,15 +42,6 @@ public void ConfigureServices(IServiceCollection services) // Create the Bot Adapter with error handling enabled. services.AddSingleton(); - // Create the storage we'll be using for User and Conversation state. (Memory is great for testing purposes.) - services.AddSingleton(); - - // Create the User state. (Used in this bot's Dialog implementation.) - services.AddSingleton(); - - // Create the Conversation state. (Used by the Dialog system itself.) - services.AddSingleton(); - // Create the bot as a transient. In this case the ASP Controller is expecting an IBot. services.AddTransient(); @@ -61,7 +52,6 @@ public void ConfigureServices(IServiceCollection services) } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { @@ -74,7 +64,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) .UseStaticFiles() .UseWebSockets() .UseRouting() - .UseAuthorization() .UseEndpoints(endpoints => { endpoints.MapControllers(); diff --git a/samples/csharp_dotnetcore/86.bot-authentication-fic/appsettings.json b/samples/csharp_dotnetcore/86.bot-authentication-fic/appsettings.json index b3e43e309b..c165f1dafe 100644 --- a/samples/csharp_dotnetcore/86.bot-authentication-fic/appsettings.json +++ b/samples/csharp_dotnetcore/86.bot-authentication-fic/appsettings.json @@ -2,5 +2,5 @@ "MicrosoftAppType": "", "MicrosoftAppId": "", "MicrosoftAppClientId": "", - "MicrosoftAppTenantId": "", + "MicrosoftAppTenantId": "" } diff --git a/samples/csharp_dotnetcore/86.bot-authentication-fic/wwwroot/default.htm b/samples/csharp_dotnetcore/86.bot-authentication-fic/wwwroot/default.htm index ab3f8fdbb7..70696a1e0f 100644 --- a/samples/csharp_dotnetcore/86.bot-authentication-fic/wwwroot/default.htm +++ b/samples/csharp_dotnetcore/86.bot-authentication-fic/wwwroot/default.htm @@ -4,7 +4,7 @@ - bot_authentication_fic + AuthFederatedCredBot