diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 88c6d89216f4a..b15c60d6c73d2 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -71,6 +71,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0 + uses: github/codeql-action/upload-sarif@29d86d22a34ea372b1bbf3b2dced2e25ca6b3384 # v3.26.1 with: sarif_file: results.sarif diff --git a/docs/ai/how-to/snippets/semantic-kernel/semantic-kernel.csproj b/docs/ai/how-to/snippets/semantic-kernel/semantic-kernel.csproj index 70420c6643e93..afee19b2cecc3 100644 --- a/docs/ai/how-to/snippets/semantic-kernel/semantic-kernel.csproj +++ b/docs/ai/how-to/snippets/semantic-kernel/semantic-kernel.csproj @@ -15,7 +15,7 @@ - + diff --git a/docs/ai/tutorials/snippets/llm-eval/llm-eval.csproj b/docs/ai/tutorials/snippets/llm-eval/llm-eval.csproj index 169ad157b144b..267fa57cbc91b 100644 --- a/docs/ai/tutorials/snippets/llm-eval/llm-eval.csproj +++ b/docs/ai/tutorials/snippets/llm-eval/llm-eval.csproj @@ -12,7 +12,7 @@ - + diff --git a/docs/azure/TOC.yml b/docs/azure/TOC.yml index 5e58f198ae13d..0e7e95385a700 100644 --- a/docs/azure/TOC.yml +++ b/docs/azure/TOC.yml @@ -67,6 +67,8 @@ href: ./sdk/authentication/create-token-credentials-from-configuration.md - name: Additional auth methods href: ./sdk/authentication/additional-methods.md + - name: Credential chains + href: ./sdk/authentication/credential-chains.md - name: Resource management href: ./sdk/resource-management.md - name: Dependency injection @@ -118,4 +120,4 @@ - name: All samples href: /samples/browse/?languages=csharp%2Caspx-csharp%2Cfsharp%2Cvb - name: API reference - href: /dotnet/api/overview/azure/?view=azure-dotnet&preserve-view=true \ No newline at end of file + href: /dotnet/api/overview/azure/?view=azure-dotnet&preserve-view=true diff --git a/docs/azure/includes/dotnet-all.md b/docs/azure/includes/dotnet-all.md index 562be6cf88aaf..12e7b73f6efbd 100644 --- a/docs/azure/includes/dotnet-all.md +++ b/docs/azure/includes/dotnet-all.md @@ -61,7 +61,7 @@ | Maps Geolocation | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.Maps.Geolocation/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/Maps.Geolocation-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Geolocation_1.0.0-beta.2/sdk/maps/Azure.Maps.Geolocation/) | | Maps Render | NuGet [2.0.0-beta.1](https://www.nuget.org/packages/Azure.Maps.Rendering/2.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Maps.Rendering-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Rendering_2.0.0-beta.1/sdk/maps/Azure.Maps.Rendering/) | | Maps Route | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.Maps.Routing/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/Maps.Routing-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Routing_1.0.0-beta.3/sdk/maps/Azure.Maps.Routing/) | -| Maps Search | NuGet [2.0.0-beta.1](https://www.nuget.org/packages/Azure.Maps.Search/2.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Maps.Search-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Search_2.0.0-beta.1/sdk/maps/Azure.Maps.Search/) | +| Maps Search | NuGet [2.0.0-beta.2](https://www.nuget.org/packages/Azure.Maps.Search/2.0.0-beta.2) | [docs](/dotnet/api/overview/azure/Maps.Search-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Search_2.0.0-beta.2/sdk/maps/Azure.Maps.Search/) | | Media Analytics Edge | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.Media.Analytics.Edge/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Media.Analytics.Edge-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Media.Analytics.Edge_1.0.0-beta.1/sdk/mediaservices/Azure.Media.Analytics.Edge) | | Metrics Advisor | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.MetricsAdvisor/1.1.0) | [docs](/dotnet/api/overview/azure/AI.MetricsAdvisor-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.MetricsAdvisor_1.1.0/sdk/metricsadvisor/Azure.AI.MetricsAdvisor/) | | Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents | NuGet [1.0.1](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents/1.0.1) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents_1.0.1/sdk/entra/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents/) | @@ -426,8 +426,8 @@ | Search - Common | NuGet [10.1.0](https://www.nuget.org/packages/Microsoft.Azure.Search.Common/10.1.0) | | GitHub [10.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Search.Common_10.1.0/sdk/search/Microsoft.Azure.Search.Common/) | | Search - Data | NuGet [10.1.0](https://www.nuget.org/packages/Microsoft.Azure.Search.Data/10.1.0) | | GitHub [10.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Search.Data_10.1.0/sdk/search/Microsoft.Azure.Search.Data/) | | Search - Service | NuGet [10.1.0](https://www.nuget.org/packages/Microsoft.Azure.Search.Service/10.1.0) | | GitHub [10.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.Search.Service_10.1.0/sdk/search/Microsoft.Azure.Search.Service/) | -| Speech | NuGet [1.38.0](https://www.nuget.org/packages/Microsoft.CognitiveServices.Speech/1.38.0) | | | -| Speech Remote Conversation | NuGet [1.38.0](https://www.nuget.org/packages/Microsoft.CognitiveServices.Speech.Remoteconversation/1.38.0) | | | +| Speech | NuGet [1.40.0](https://www.nuget.org/packages/Microsoft.CognitiveServices.Speech/1.40.0) | | | +| Speech Remote Conversation | NuGet [1.40.0](https://www.nuget.org/packages/Microsoft.CognitiveServices.Speech.Remoteconversation/1.40.0) | | | | Speech Xamarin iOS | NuGet [1.25.0](https://www.nuget.org/packages/Microsoft.CognitiveServices.Speech.Xamarin.iOS/1.25.0) | | | | Spell Check | NuGet [4.1.0-preview.1](https://www.nuget.org/packages/Microsoft.Azure.CognitiveServices.Language.SpellCheck/4.1.0-preview.1) | | GitHub [4.1.0-preview.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.CognitiveServices.Language.SpellCheck_4.1.0-preview.1/sdk/cognitiveservices/Language.SpellCheck) | | Spring Cloud Client | NuGet [2.0.0-preview.3](https://www.nuget.org/packages/Microsoft.Azure.SpringCloud.Client/2.0.0-preview.3) | | | diff --git a/docs/azure/includes/dotnet-new.md b/docs/azure/includes/dotnet-new.md index d4e0cd456e1c9..1ddd29b125202 100644 --- a/docs/azure/includes/dotnet-new.md +++ b/docs/azure/includes/dotnet-new.md @@ -62,7 +62,7 @@ | Maps Geolocation | NuGet [1.0.0-beta.2](https://www.nuget.org/packages/Azure.Maps.Geolocation/1.0.0-beta.2) | [docs](/dotnet/api/overview/azure/Maps.Geolocation-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Geolocation_1.0.0-beta.2/sdk/maps/Azure.Maps.Geolocation/) | | Maps Render | NuGet [2.0.0-beta.1](https://www.nuget.org/packages/Azure.Maps.Rendering/2.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Maps.Rendering-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Rendering_2.0.0-beta.1/sdk/maps/Azure.Maps.Rendering/) | | Maps Route | NuGet [1.0.0-beta.3](https://www.nuget.org/packages/Azure.Maps.Routing/1.0.0-beta.3) | [docs](/dotnet/api/overview/azure/Maps.Routing-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.3](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Routing_1.0.0-beta.3/sdk/maps/Azure.Maps.Routing/) | -| Maps Search | NuGet [2.0.0-beta.1](https://www.nuget.org/packages/Azure.Maps.Search/2.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Maps.Search-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Search_2.0.0-beta.1/sdk/maps/Azure.Maps.Search/) | +| Maps Search | NuGet [2.0.0-beta.2](https://www.nuget.org/packages/Azure.Maps.Search/2.0.0-beta.2) | [docs](/dotnet/api/overview/azure/Maps.Search-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [2.0.0-beta.2](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Maps.Search_2.0.0-beta.2/sdk/maps/Azure.Maps.Search/) | | Media Analytics Edge | NuGet [1.0.0-beta.1](https://www.nuget.org/packages/Azure.Media.Analytics.Edge/1.0.0-beta.1) | [docs](/dotnet/api/overview/azure/Media.Analytics.Edge-readme?view=azure-dotnet-preview&preserve-view=true) | GitHub [1.0.0-beta.1](https://github.com/Azure/azure-sdk-for-net/tree/Azure.Media.Analytics.Edge_1.0.0-beta.1/sdk/mediaservices/Azure.Media.Analytics.Edge) | | Metrics Advisor | NuGet [1.1.0](https://www.nuget.org/packages/Azure.AI.MetricsAdvisor/1.1.0) | [docs](/dotnet/api/overview/azure/AI.MetricsAdvisor-readme) | GitHub [1.1.0](https://github.com/Azure/azure-sdk-for-net/tree/Azure.AI.MetricsAdvisor_1.1.0/sdk/metricsadvisor/Azure.AI.MetricsAdvisor/) | | Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents | NuGet [1.0.1](https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents/1.0.1) | [docs](/dotnet/api/overview/azure/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents-readme) | GitHub [1.0.1](https://github.com/Azure/azure-sdk-for-net/tree/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents_1.0.1/sdk/entra/Microsoft.Azure.WebJobs.Extensions.AuthenticationEvents/) | diff --git a/docs/azure/sdk/authentication/credential-chains.md b/docs/azure/sdk/authentication/credential-chains.md new file mode 100644 index 0000000000000..6e88fb09f9dfa --- /dev/null +++ b/docs/azure/sdk/authentication/credential-chains.md @@ -0,0 +1,132 @@ +--- +title: 'Credential chains in the Azure Identity library for .NET' +description: 'This article describes the DefaultAzureCredential and ChainedTokenCredential classes in the Azure Identity library.' +ms.topic: conceptual +ms.date: 08/13/2024 +--- + +# Credential chains in the Azure Identity library for .NET + +The Azure Identity library provides *credentials*—public classes derived from the Azure Core library's [TokenCredential](/dotnet/api/azure.core.tokencredential?view=azure-dotnet&preserve-view=true) class. A credential represents a distinct authentication flow for acquiring an access token from Microsoft Entra ID. These credentials can be chained together to form an ordered sequence of authentication mechanisms to be attempted. + +## How a chained credential works + +At runtime, a credential chain attempts to authenticate using the sequence's first credential. If that credential fails to acquire an access token, the next credential in the sequence is attempted, and so on, until an access token is successfully obtained. The following sequence diagram illustrates this behavior: + +:::image type="content" source="../media/mermaidjs/ChainSequence.svg" alt-text="Credential chain sequence diagram"::: + +## Why use credential chains + +A chained credential can offer the following benefits: + +- **Environment awareness**: Automatically selects the most appropriate credential based on the environment in which the app is running. Without it, you'd have to write code like this: + + :::code language="csharp" source="../snippets/authentication/credential-chains/Program.cs" id="snippet_NoChain"::: + +- **Seamless transitions**: Your app can move from local development to your staging or production environment without changing authentication code. +- **Improved resiliency**: Includes a fallback mechanism that moves to the next credential when the prior fails to acquire an access token. + +## How to choose a chained credential + +There are two disparate philosophies to credential chaining: + +- **"Tear down" a chain**: Start with a preconfigured chain and exclude what you don't need. For this approach, see the [DefaultAzureCredential overview](#defaultazurecredential-overview) section. +- **"Build up" a chain**: Start with an empty chain and include only what you need. For this approach, see the [ChainedTokenCredential overview](#chainedtokencredential-overview) section. + +## DefaultAzureCredential overview + +[DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet&preserve-view=true) is an opinionated, preconfigured chain of credentials. It's designed to support many environments, along with the most common authentication flows and developer tools. In graphical form, the underlying chain looks like this: + +:::image type="content" source="../media/mermaidjs/DefaultAzureCredentialAuthFlow.svg" alt-text="DefaultAzureCredential auth flowchart"::: + +The order in which `DefaultAzureCredential` attempts credentials follows. + +| Order | Credential | Description | Enabled by default? | +|-------|---------------------|-------------|---------------------| +| 1 | [Environment][env-cred] |Reads a collection of environment variables to determine if an application service principal (application user) is configured for the app. If so, `DefaultAzureCredential` uses these values to authenticate the app to Azure. This method is most often used in server environments but can also be used when developing locally. | Yes | +| 2 | [Workload Identity][wi-cred] |If the app is deployed to an Azure host with Workload Identity enabled, authenticate that account. | Yes | +| 3 | [Managed Identity][mi-cred] |If the app is deployed to an Azure host with Managed Identity enabled, authenticate the app to Azure using that Managed Identity. | Yes | +| 4 | [Visual Studio][vs-cred] |If the developer authenticated to Azure by logging into Visual Studio, authenticate the app to Azure using that same account. | Yes | +| 5 | [Azure CLI][az-cred] |If the developer authenticated to Azure using Azure CLI's `az login` command, authenticate the app to Azure using that same account. | Yes | +| 6 | [Azure PowerShell][pwsh-cred] |If the developer authenticated to Azure using Azure PowerShell's `Connect-AzAccount` cmdlet, authenticate the app to Azure using that same account. | Yes | +| 7 | [Azure Developer CLI][azd-cred] |If the developer authenticated to Azure using Azure Developer CLI's `azd auth login` command, authenticate with that account. | Yes | +| 8 | [Interactive browser][int-cred] |If enabled, interactively authenticate the developer via the current system's default browser. | No | + +[env-cred]: /dotnet/api/azure.identity.environmentcredential?view=azure-dotnet&preserve-view=true +[wi-cred]: /dotnet/api/azure.identity.workloadidentitycredential?view=azure-dotnet&preserve-view=true +[mi-cred]: /dotnet/api/azure.identity.managedidentitycredential?view=azure-dotnet&preserve-view=true +[vs-cred]: /dotnet/api/azure.identity.visualstudiocredential?view=azure-dotnet&preserve-view=true +[az-cred]: /dotnet/api/azure.identity.azureclicredential?view=azure-dotnet&preserve-view=true +[pwsh-cred]: /dotnet/api/azure.identity.azurepowershellcredential?view=azure-dotnet&preserve-view=true +[azd-cred]: /dotnet/api/azure.identity.azuredeveloperclicredential?view=azure-dotnet&preserve-view=true +[int-cred]: /dotnet/api/azure.identity.interactivebrowsercredential?view=azure-dotnet&preserve-view=true + +In its simplest form, you can use the parameterless version of `DefaultAzureCredential` as follows: + +:::code language="csharp" source="../snippets/authentication/credential-chains/Program.cs" id="snippet_Dac"::: + +### How to customize DefaultAzureCredential + +To remove a credential from `DefaultAzureCredential`, use the corresponding `Exclude`-prefixed property in [DefaultAzureCredentialOptions](/dotnet/api/azure.identity.defaultazurecredentialoptions?view=azure-dotnet&preserve-view=true#properties). For example: + +:::code language="csharp" source="../snippets/authentication/credential-chains/Program.cs" id="snippet_DacExcludes" highlight="4-5"::: + +In the preceding code sample, `EnvironmentCredential` and `WorkloadIdentityCredential` are removed from the credential chain. As a result, the first credential to be attempted is `ManagedIdentityCredential`. The modified chain looks like this: + +:::image type="content" source="../media/mermaidjs/DefaultAzureCredentialExcludes.svg" alt-text="DefaultAzureCredential using Excludes properties"::: + +> [!NOTE] +> `InteractiveBrowserCredential` is excluded by default and therefore isn't shown in the preceding diagram. To include `InteractiveBrowserCredential`, use constructor . + +As more `Exclude`-prefixed properties are set to `true` (credential exclusions are configured), the advantages of using `DefaultAzureCredential` diminish. In such cases, `ChainedTokenCredential` is a better choice and requires less code. To illustrate, these two code samples behave the same way: + +### [DefaultAzureCredential](#tab/dac) + +:::code language="csharp" source="../snippets/authentication/credential-chains/Program.cs" id="snippet_DacEquivalents"::: + +### [ChainedTokenCredential](#tab/ctc) + +:::code language="csharp" source="../snippets/authentication/credential-chains/Program.cs" id="snippet_CtcEquivalents"::: + +--- + +## ChainedTokenCredential overview + +[ChainedTokenCredential](/dotnet/api/azure.identity.chainedtokencredential?view=azure-dotnet&preserve-view=true) is an empty chain to which you add credentials to suit your app's needs. For example: + +:::code language="csharp" source="../snippets/authentication/credential-chains/Program.cs" id="snippet_Ctc"::: + +The preceding code sample creates a tailored credential chain comprised of two credentials. The user-assigned managed identity variant of `ManagedIdentityCredential` is attempted first, followed by `VisualStudioCredential`, if necessary. In graphical form, the chain looks like this: + +:::image type="content" source="../media/mermaidjs/ChainedTokenCredentialAuthFlow.svg" alt-text="ChainedTokenCredential"::: + +> [!TIP] +> For improved performance, optimize credential ordering in `ChainedTokenCredential` for your production environment. Credentials intended for use in the local development environment should be added last. + +## Usage guidance for DefaultAzureCredential + +`DefaultAzureCredential` is undoubtedly the easiest way to get started with the Azure Identity library, but with that convenience comes tradeoffs. Once you deploy your app to Azure, you should understand the app's authentication requirements. For that reason, strongly consider moving from `DefaultAzureCredential` to one of the following solutions: + +- A specific `TokenCredential` implementation, such as `ManagedIdentityCredential`. See the [**Derived** list](/dotnet/api/azure.core.tokencredential?view=azure-dotnet&preserve-view=true#definition) for options. +- A pared-down `ChainedTokenCredential` implementation optimized for the Azure environment in which your app runs. + +Here's why: + +- **Debugging challenges**: When authentication fails, it can be challenging to debug and identify the offending credential. You must enable logging to see the progression from one credential to the next and the success/failure status of each. For more information, see [Debug a chained credential](#debug-a-chained-credential). +- **Performance overhead**: The process of sequentially trying multiple credentials can introduce performance overhead. For example, when running on a local development machine, managed identity is unavailable. Consequently, `ManagedIdentityCredential` always fails in the local development environment, unless explicitly disabled via its corresponding `Exclude`-prefixed property. +- **Unpredictable behavior**: `DefaultAzureCredential` checks for the presence of certain [environment variables](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/README.md#environment-variables). It's possible that someone could add or modify these environment variables at the system level on the host machine. Those changes apply globally and therefore alter the behavior of `DefaultAzureCredential` at runtime in any app running on that machine. + +## Debug a chained credential + +To diagnose an unexpected issue or to understand what a chained credential is doing, [enable logging](../logging.md) in your app. Optionally, filter the logs to only those events emitted from the Azure Identity library. For example: + +:::code language="csharp" source="../snippets/authentication/credential-chains/Program.cs" id="snippet_FilteredLogging"::: + +For illustration purposes, assume the parameterless form of `DefaultAzureCredential` was used to authenticate a request to a Log Analytics workspace. The app ran in the local development environment, and Visual Studio was authenticated to an Azure account. The next time the app ran, the following pertinent entries appeared in the output: + +:::code language="output" source="../snippets/authentication/credential-chains/dac-logs.txt"::: + +In the preceding output, notice that: + +- `EnvironmentCredential`, `WorkloadIdentityCredential`, and `ManagedIdentityCredential` each failed to acquire a Microsoft Entra access token, in that order. +- The `DefaultAzureCredential credential selected:`-prefixed entry indicates the credential that was selected—`VisualStudioCredential` in this case. Since `VisualStudioCredential` succeeded, no credentials beyond it were used. diff --git a/docs/azure/sdk/authentication/index.md b/docs/azure/sdk/authentication/index.md index 4d800192cc48b..3c62834dadf98 100644 --- a/docs/azure/sdk/authentication/index.md +++ b/docs/azure/sdk/authentication/index.md @@ -62,20 +62,3 @@ When an app is run on a developer's workstation during local development, it mus ## Use DefaultAzureCredential in an application [!INCLUDE [Implement DefaultAzureCredential](<../includes/implement-defaultazurecredential.md>)] - -### Explore the sequence of DefaultAzureCredential authentication methods - -Internally, `DefaultAzureCredential` implements a chain of credential providers for authenticating applications to Azure resources. Each credential provider is able to detect if credentials of that type are configured for the app. `DefaultAzureCredential` sequentially checks each provider in order and uses the credentials from the first provider that has credentials configured. - -The order and locations in which `DefaultAzureCredential` looks for credentials is found at [DefaultAzureCredential](/dotnet/api/overview/azure/identity-readme?view=azure-dotnet&preserve-view=true#defaultazurecredential). - -| Credential type | Description | -|-------------------------------|-------------| -| Environment | `DefaultAzureCredential` reads a set of environment variables to determine if an application service principal (application user) has been set for the app. If so, `DefaultAzureCredential` uses these values to authenticate the app to Azure.

This method is most often used in server environments but can also be used when developing locally. | -| Workload Identity | If the app is deployed to an Azure host with Workload Identity enabled, `DefaultAzureCredential` will authenticate that account. | -| Managed Identity | If the app is deployed to an Azure host with Managed Identity enabled, `DefaultAzureCredential` will authenticate the app to Azure using that Managed Identity. Authentication using a Managed Identity is discussed in the [Authentication in server environments](#authentication-in-server-environments) section of this document.

This method is only available when the app is hosted in Azure using a service like Azure App Service, Azure Functions, or Azure Virtual Machines. | -| Visual Studio | If the developer has authenticated to Azure by logging into Visual Studio, `DefaultAzureCredential` will authenticate the app to Azure using that same account. | -| Azure CLI | If the developer has authenticated to Azure using Azure CLI's `az login` command, `DefaultAzureCredential` will authenticate the app to Azure using that same account. | -| Azure PowerShell | If the developer has authenticated to Azure using Azure PowerShell's `Connect-AzAccount` cmdlet, `DefaultAzureCredential` will authenticate the app to Azure using that same account. | -| Azure Developer CLI | If the developer has authenticated to Azure using Azure Developer CLI's `azd auth login` command, `DefaultAzureCredential` will authenticate with that account. | -| Interactive | If enabled, `DefaultAzureCredential` will interactively authenticate the developer via the current system's default browser. By default, this option is disabled. | diff --git a/docs/azure/sdk/includes/mermaidjs/ChainSequence.md b/docs/azure/sdk/includes/mermaidjs/ChainSequence.md new file mode 100644 index 0000000000000..10982f7638ef1 --- /dev/null +++ b/docs/azure/sdk/includes/mermaidjs/ChainSequence.md @@ -0,0 +1,35 @@ +--- +ms.topic: include +ms.date: 08/07/2024 +--- + +```mermaid +%% STEPS TO GENERATE IMAGE +%% ======================= +%% 1. Install mermaid CLI v10.9.1 (see https://github.com/mermaid-js/mermaid-cli/blob/master/README.md): +%% npm i -g @mermaid-js/mermaid-cli@10.9.1 +%% 2. Run command: mmdc -i ChainSequence.md -o ../../media/mermaidjs/ChainSequence.svg + +sequenceDiagram + autonumber; + + participant A as .NET app; + participant B as Credential chain; + participant C as TokenCredential instance; + + A->>B: Authenticate to Microsoft Entra ID; + activate B; + B->>B: GetToken; + loop Traverse TokenCredential collection until AccessToken received + B->>C: Fetch token; + activate C; + C->>C: GetToken; + break when Result is AccessToken + C-->>B: Result; + end; + deactivate C; + end; + + B-->>A: AccessToken; + deactivate B; +``` diff --git a/docs/azure/sdk/includes/mermaidjs/ChainedTokenCredentialAuthFlow.md b/docs/azure/sdk/includes/mermaidjs/ChainedTokenCredentialAuthFlow.md new file mode 100644 index 0000000000000..e3a4efd5d0ff6 --- /dev/null +++ b/docs/azure/sdk/includes/mermaidjs/ChainedTokenCredentialAuthFlow.md @@ -0,0 +1,29 @@ +--- +ms.topic: include +ms.date: 08/07/2024 +--- + +```mermaid +%% STEPS TO GENERATE IMAGE +%% ======================= +%% 1. Install mermaid CLI v10.9.1 (see https://github.com/mermaid-js/mermaid-cli/blob/master/README.md): +%% npm i -g @mermaid-js/mermaid-cli@10.9.1 +%% 2. Run command: mmdc -i ChainedTokenCredentialAuthFlow.md -o ../../media/mermaidjs/ChainedTokenCredentialAuthFlow.svg + +%%{ + init: { + 'theme': 'base', + 'themeVariables': { + 'tertiaryBorderColor': '#fff', + 'tertiaryColor': '#fff' + } + } +}%% + +flowchart LR; + C(Managed Identity):::deployed --> D(Visual Studio):::developer; + + %% Define styles for credential type boxes + classDef deployed fill:#95C37E, stroke:#71AD4C, stroke-width:2px; + classDef developer fill:#F5AF6F, stroke:#EB7C39, stroke-width:2px; +``` diff --git a/docs/azure/sdk/includes/mermaidjs/DefaultAzureCredentialAuthFlow.md b/docs/azure/sdk/includes/mermaidjs/DefaultAzureCredentialAuthFlow.md new file mode 100644 index 0000000000000..377eb05685e99 --- /dev/null +++ b/docs/azure/sdk/includes/mermaidjs/DefaultAzureCredentialAuthFlow.md @@ -0,0 +1,51 @@ +--- +ms.topic: include +ms.date: 08/07/2024 +--- + +```mermaid +%% STEPS TO GENERATE IMAGE +%% ======================= +%% 1. Install mermaid CLI v10.9.1 (see https://github.com/mermaid-js/mermaid-cli/blob/master/README.md): +%% npm i -g @mermaid-js/mermaid-cli@10.9.1 +%% 2. Run command: mmdc -i DefaultAzureCredentialAuthFlow.md -o ../../media/mermaidjs/DefaultAzureCredentialAuthFlow.svg + +%%{ + init: { + 'theme': 'base', + 'themeVariables': { + 'tertiaryBorderColor': '#fff', + 'tertiaryColor': '#fff' + } + } +}%% + +flowchart LR; + accTitle: DefaultAzureCredential authentication flow; + accDescr: Flowchart showing the credential chain implemented by DefaultAzureCredential; + + subgraph CREDENTIAL TYPES; + direction LR; + Deployed(Deployed service):::deployed ~~~ Developer(Developer tool):::developer ~~~ Interactive(Interactive):::interactive; + end; + + subgraph CREDENTIALS; + direction LR; + A(Environment):::deployed --> B(Workload Identity):::deployed --> C(Managed Identity):::deployed --> D(Visual Studio):::developer --> E(Azure CLI):::developer --> F(Azure PowerShell):::developer --> G(Azure Developer CLI):::developer --> H(Interactive browser):::interactive; + end; + + %% Define styles for credential type boxes + classDef deployed fill:#95C37E, stroke:#71AD4C, stroke-width:2px; + classDef developer fill:#F5AF6F, stroke:#EB7C39, stroke-width:2px; + classDef interactive fill:#A5A5A5, stroke:#828282, stroke-dasharray:5 5, stroke-width:2px; + + %% Add API ref links to credential type boxes + click A "https://learn.microsoft.com/dotnet/api/azure.identity.environmentcredential?view=azure-dotnet" _blank; + click B "https://learn.microsoft.com/dotnet/api/azure.identity.workloadidentitycredential?view=azure-dotnet" _blank; + click C "https://learn.microsoft.com/dotnet/api/azure.identity.managedidentitycredential?view=azure-dotnet" _blank; + click D "https://learn.microsoft.com/dotnet/api/azure.identity.visualstudiocredential?view=azure-dotnet" _blank; + click E "https://learn.microsoft.com/dotnet/api/azure.identity.azureclicredential?view=azure-dotnet" _blank; + click F "https://learn.microsoft.com/dotnet/api/azure.identity.azurepowershellcredential?view=azure-dotnet" _blank; + click G "https://learn.microsoft.com/dotnet/api/azure.identity.azuredeveloperclicredential?view=azure-dotnet" _blank + click H "https://learn.microsoft.com/dotnet/api/azure.identity.interactivebrowsercredential?view=azure-dotnet" _blank; +``` diff --git a/docs/azure/sdk/includes/mermaidjs/DefaultAzureCredentialExcludes.md b/docs/azure/sdk/includes/mermaidjs/DefaultAzureCredentialExcludes.md new file mode 100644 index 0000000000000..10769fb09f86e --- /dev/null +++ b/docs/azure/sdk/includes/mermaidjs/DefaultAzureCredentialExcludes.md @@ -0,0 +1,29 @@ +--- +ms.topic: include +ms.date: 08/07/2024 +--- + +```mermaid +%% STEPS TO GENERATE IMAGE +%% ======================= +%% 1. Install mermaid CLI v10.9.1 (see https://github.com/mermaid-js/mermaid-cli/blob/master/README.md): +%% npm i -g @mermaid-js/mermaid-cli@10.9.1 +%% 2. Run command: mmdc -i DefaultAzureCredentialExcludes.md -o ../../media/mermaidjs/DefaultAzureCredentialExcludes.svg + +%%{ + init: { + 'theme': 'base', + 'themeVariables': { + 'tertiaryBorderColor': '#fff', + 'tertiaryColor': '#fff' + } + } +}%% + +flowchart LR; + C(Managed Identity):::deployed --> D(Visual Studio):::developer --> E(Azure CLI):::developer --> F(Azure PowerShell):::developer --> G(Azure Developer CLI):::developer; + + %% Define styles for credential type boxes + classDef deployed fill:#95C37E, stroke:#71AD4C, stroke-width:2px; + classDef developer fill:#F5AF6F, stroke:#EB7C39, stroke-width:2px; +``` diff --git a/docs/azure/sdk/media/mermaidjs/ChainSequence.svg b/docs/azure/sdk/media/mermaidjs/ChainSequence.svg new file mode 100644 index 0000000000000..61649cf18feb8 --- /dev/null +++ b/docs/azure/sdk/media/mermaidjs/ChainSequence.svg @@ -0,0 +1 @@ +TokenCredential instanceCredential chain.NET appTokenCredential instanceCredential chain.NET appbreak[when Result isAccessToken]loop[TraverseTokenCredentialcollection untilAccessToken received]Authenticate to Microsoft Entra ID1GetToken2Fetch token3GetToken4Result5AccessToken6 \ No newline at end of file diff --git a/docs/azure/sdk/media/mermaidjs/ChainedTokenCredentialAuthFlow.svg b/docs/azure/sdk/media/mermaidjs/ChainedTokenCredentialAuthFlow.svg new file mode 100644 index 0000000000000..9b237011b86a1 --- /dev/null +++ b/docs/azure/sdk/media/mermaidjs/ChainedTokenCredentialAuthFlow.svg @@ -0,0 +1 @@ +
Managed Identity
Visual Studio
\ No newline at end of file diff --git a/docs/azure/sdk/media/mermaidjs/DefaultAzureCredentialAuthFlow.svg b/docs/azure/sdk/media/mermaidjs/DefaultAzureCredentialAuthFlow.svg new file mode 100644 index 0000000000000..f60052a3a0662 --- /dev/null +++ b/docs/azure/sdk/media/mermaidjs/DefaultAzureCredentialAuthFlow.svg @@ -0,0 +1 @@ +DefaultAzureCredential authentication flow;Flowchart showing the credential chain implemented by DefaultAzureCredential;
CREDENTIALS
Interactive browser
Environment
Workload Identity
Managed Identity
Visual Studio
Azure CLI
Azure PowerShell
Azure Developer CLI
CREDENTIAL TYPES
Interactive
Deployed service
Developer tool
\ No newline at end of file diff --git a/docs/azure/sdk/media/mermaidjs/DefaultAzureCredentialExcludes.svg b/docs/azure/sdk/media/mermaidjs/DefaultAzureCredentialExcludes.svg new file mode 100644 index 0000000000000..d8f1ff33f5604 --- /dev/null +++ b/docs/azure/sdk/media/mermaidjs/DefaultAzureCredentialExcludes.svg @@ -0,0 +1 @@ +
Managed Identity
Visual Studio
Azure CLI
Azure PowerShell
Azure Developer CLI
\ No newline at end of file diff --git a/docs/azure/sdk/snippets/authentication/credential-chains/AuthenticationSampleApp.csproj b/docs/azure/sdk/snippets/authentication/credential-chains/AuthenticationSampleApp.csproj new file mode 100644 index 0000000000000..b8ea77858086c --- /dev/null +++ b/docs/azure/sdk/snippets/authentication/credential-chains/AuthenticationSampleApp.csproj @@ -0,0 +1,17 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + diff --git a/docs/azure/sdk/snippets/authentication/credential-chains/Program.cs b/docs/azure/sdk/snippets/authentication/credential-chains/Program.cs new file mode 100644 index 0000000000000..06eb79507d8c2 --- /dev/null +++ b/docs/azure/sdk/snippets/authentication/credential-chains/Program.cs @@ -0,0 +1,116 @@ +using System.Diagnostics.Tracing; +using Azure.Core; +using Azure.Core.Diagnostics; +using Azure.Identity; +using Microsoft.Extensions.Azure; + +var userAssignedClientId = ""; +var builder = WebApplication.CreateBuilder(args); + +#region snippet_FilteredLogging +using AzureEventSourceListener listener = new((args, message) => +{ + if (args is { EventSource.Name: "Azure-Identity" }) + { + Console.WriteLine(message); + } +}, EventLevel.LogAlways); +#endregion snippet_FilteredLogging + +builder.Services.AddAzureClients(clientBuilder => +{ + clientBuilder.AddBlobServiceClient( + new Uri("https://.blob.core.windows.net")); + #region snippet_Dac + clientBuilder.UseCredential(new DefaultAzureCredential()); + #endregion snippet_Dac + + #region snippet_DacExcludes + clientBuilder.UseCredential(new DefaultAzureCredential( + new DefaultAzureCredentialOptions + { + ExcludeEnvironmentCredential = true, + ExcludeWorkloadIdentityCredential = true, + ManagedIdentityClientId = userAssignedClientId, + })); + #endregion snippet_DacExcludes + + #region snippet_Ctc + clientBuilder.UseCredential(new ChainedTokenCredential( + new ManagedIdentityCredential(clientId: userAssignedClientId), + new VisualStudioCredential())); + #endregion snippet_Ctc +}); + +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +#region snippet_NoChain +TokenCredential credential; + +if (app.Environment.IsProduction() || app.Environment.IsStaging()) +{ + credential = new ManagedIdentityCredential(clientId: userAssignedClientId); +} +else +{ + // local development environment + credential = new VisualStudioCredential(); +} +#endregion snippet_NoChain + +#region snippet_DacEquivalents +credential = new DefaultAzureCredential( + new DefaultAzureCredentialOptions + { + ExcludeEnvironmentCredential = true, + ExcludeWorkloadIdentityCredential = true, + ExcludeAzureCliCredential = true, + ExcludeAzurePowerShellCredential = true, + ExcludeAzureDeveloperCliCredential = true, + ManagedIdentityClientId = userAssignedClientId + }); +#endregion + +#region snippet_CtcEquivalents +credential = new ChainedTokenCredential( + new ManagedIdentityCredential(clientId: userAssignedClientId), + new VisualStudioCredential()); +#endregion + +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +var summaries = new[] +{ + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" +}; + +app.MapGet("/weatherforecast", () => +{ + var forecast = Enumerable.Range(1, 5).Select(index => + new WeatherForecast + ( + DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + Random.Shared.Next(-20, 55), + summaries[Random.Shared.Next(summaries.Length)] + )) + .ToArray(); + return forecast; +}) +.WithName("GetWeatherForecast") +.WithOpenApi(); + +app.Run(); + +internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary) +{ + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); +} diff --git a/docs/azure/sdk/snippets/authentication/credential-chains/Properties/launchSettings.json b/docs/azure/sdk/snippets/authentication/credential-chains/Properties/launchSettings.json new file mode 100644 index 0000000000000..749eb1b53250e --- /dev/null +++ b/docs/azure/sdk/snippets/authentication/credential-chains/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:43556", + "sslPort": 44331 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5268", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7076;http://localhost:5268", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/docs/azure/sdk/snippets/authentication/credential-chains/appsettings.Development.json b/docs/azure/sdk/snippets/authentication/credential-chains/appsettings.Development.json new file mode 100644 index 0000000000000..0c208ae9181e5 --- /dev/null +++ b/docs/azure/sdk/snippets/authentication/credential-chains/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/docs/azure/sdk/snippets/authentication/credential-chains/appsettings.json b/docs/azure/sdk/snippets/authentication/credential-chains/appsettings.json new file mode 100644 index 0000000000000..10f68b8c8b4f7 --- /dev/null +++ b/docs/azure/sdk/snippets/authentication/credential-chains/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/docs/azure/sdk/snippets/authentication/credential-chains/dac-logs.txt b/docs/azure/sdk/snippets/authentication/credential-chains/dac-logs.txt new file mode 100644 index 0000000000000..65a75e4608412 --- /dev/null +++ b/docs/azure/sdk/snippets/authentication/credential-chains/dac-logs.txt @@ -0,0 +1,11 @@ +DefaultAzureCredential.GetToken invoked. Scopes: [ https://api.loganalytics.io//.default ] ParentRequestId: d7ef15d1-50f8-451d-afeb-6b06297a3342 +EnvironmentCredential.GetToken invoked. Scopes: [ https://api.loganalytics.io//.default ] ParentRequestId: d7ef15d1-50f8-451d-afeb-6b06297a3342 +EnvironmentCredential.GetToken was unable to retrieve an access token. Scopes: [ https://api.loganalytics.io//.default ] ParentRequestId: d7ef15d1-50f8-451d-afeb-6b06297a3342 Exception: Azure.Identity.CredentialUnavailableException (0x80131500): EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot +WorkloadIdentityCredential.GetToken invoked. Scopes: [ https://api.loganalytics.io//.default ] ParentRequestId: d7ef15d1-50f8-451d-afeb-6b06297a3342 +WorkloadIdentityCredential.GetToken was unable to retrieve an access token. Scopes: [ https://api.loganalytics.io//.default ] ParentRequestId: d7ef15d1-50f8-451d-afeb-6b06297a3342 Exception: Azure.Identity.CredentialUnavailableException (0x80131500): WorkloadIdentityCredential authentication unavailable. The workload options are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/workloadidentitycredential/troubleshoot +ManagedIdentityCredential.GetToken invoked. Scopes: [ https://api.loganalytics.io//.default ] ParentRequestId: d7ef15d1-50f8-451d-afeb-6b06297a3342 +ManagedIdentityCredential.GetToken was unable to retrieve an access token. Scopes: [ https://api.loganalytics.io//.default ] ParentRequestId: d7ef15d1-50f8-451d-afeb-6b06297a3342 Exception: Azure.Identity.CredentialUnavailableException (0x80131500): ManagedIdentityCredential authentication unavailable. No response received from the managed identity endpoint. +VisualStudioCredential.GetToken invoked. Scopes: [ https://api.loganalytics.io//.default ] ParentRequestId: d7ef15d1-50f8-451d-afeb-6b06297a3342 +VisualStudioCredential.GetToken succeeded. Scopes: [ https://api.loganalytics.io//.default ] ParentRequestId: d7ef15d1-50f8-451d-afeb-6b06297a3342 ExpiresOn: 2024-08-13T17:16:50.8023621+00:00 +DefaultAzureCredential credential selected: Azure.Identity.VisualStudioCredential +DefaultAzureCredential.GetToken succeeded. Scopes: [ https://api.loganalytics.io//.default ] ParentRequestId: d7ef15d1-50f8-451d-afeb-6b06297a3342 ExpiresOn: 2024-08-13T17:16:50.8023621+00:00 diff --git a/docs/core/diagnostics/snippets/exception-summary/exception-summary.csproj b/docs/core/diagnostics/snippets/exception-summary/exception-summary.csproj index edcbb8e66f582..471f627c62433 100644 --- a/docs/core/diagnostics/snippets/exception-summary/exception-summary.csproj +++ b/docs/core/diagnostics/snippets/exception-summary/exception-summary.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/core/diagnostics/snippets/health-checks/health-checks.csproj b/docs/core/diagnostics/snippets/health-checks/health-checks.csproj index 50f11e3b17471..68600d2c0cfe7 100644 --- a/docs/core/diagnostics/snippets/health-checks/health-checks.csproj +++ b/docs/core/diagnostics/snippets/health-checks/health-checks.csproj @@ -8,7 +8,7 @@ - + diff --git a/docs/core/diagnostics/snippets/lifetime-health-checks/lifetime-health-checks.csproj b/docs/core/diagnostics/snippets/lifetime-health-checks/lifetime-health-checks.csproj index 745a267a470de..be02697d89283 100644 --- a/docs/core/diagnostics/snippets/lifetime-health-checks/lifetime-health-checks.csproj +++ b/docs/core/diagnostics/snippets/lifetime-health-checks/lifetime-health-checks.csproj @@ -8,7 +8,7 @@ - + diff --git a/docs/core/diagnostics/snippets/resource-monitoring/resource-monitoring.csproj b/docs/core/diagnostics/snippets/resource-monitoring/resource-monitoring.csproj index 9c718e8083dc0..dd546ac5ee231 100644 --- a/docs/core/diagnostics/snippets/resource-monitoring/resource-monitoring.csproj +++ b/docs/core/diagnostics/snippets/resource-monitoring/resource-monitoring.csproj @@ -10,7 +10,7 @@ - + diff --git a/docs/core/docker/snippets/7.0/Worker/DotNet.ContainerImage.csproj b/docs/core/docker/snippets/7.0/Worker/DotNet.ContainerImage.csproj index db3afed2ba7de..0414f2c25f41e 100644 --- a/docs/core/docker/snippets/7.0/Worker/DotNet.ContainerImage.csproj +++ b/docs/core/docker/snippets/7.0/Worker/DotNet.ContainerImage.csproj @@ -10,6 +10,6 @@ - + diff --git a/docs/core/extensions/snippets/configuration/custom-provider/custom-provider.csproj b/docs/core/extensions/snippets/configuration/custom-provider/custom-provider.csproj index def8f9a82a4fd..3b28a042bb8d3 100644 --- a/docs/core/extensions/snippets/configuration/custom-provider/custom-provider.csproj +++ b/docs/core/extensions/snippets/configuration/custom-provider/custom-provider.csproj @@ -9,9 +9,9 @@ - - - + + + diff --git a/docs/core/extensions/snippets/localization/example/example.csproj b/docs/core/extensions/snippets/localization/example/example.csproj index 76dbee66c88ac..8cbd1d8843514 100644 --- a/docs/core/extensions/snippets/localization/example/example.csproj +++ b/docs/core/extensions/snippets/localization/example/example.csproj @@ -10,7 +10,7 @@ - + diff --git a/docs/core/resilience/snippets/http-resilience/http-resilience.csproj b/docs/core/resilience/snippets/http-resilience/http-resilience.csproj index 71f2ad05e3a3e..90ae478bcb062 100644 --- a/docs/core/resilience/snippets/http-resilience/http-resilience.csproj +++ b/docs/core/resilience/snippets/http-resilience/http-resilience.csproj @@ -20,7 +20,7 @@ - + diff --git a/docs/core/resilience/snippets/resilience/resilience.csproj b/docs/core/resilience/snippets/resilience/resilience.csproj index baffcc2296efa..e31fed693e85a 100644 --- a/docs/core/resilience/snippets/resilience/resilience.csproj +++ b/docs/core/resilience/snippets/resilience/resilience.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/core/testing/snippets/order-unit-tests/csharp/MSTest.Project/MSTest.Project.csproj b/docs/core/testing/snippets/order-unit-tests/csharp/MSTest.Project/MSTest.Project.csproj index 3419aeb574d91..0193dbb8bcd7d 100644 --- a/docs/core/testing/snippets/order-unit-tests/csharp/MSTest.Project/MSTest.Project.csproj +++ b/docs/core/testing/snippets/order-unit-tests/csharp/MSTest.Project/MSTest.Project.csproj @@ -9,8 +9,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/docs/core/testing/snippets/order-unit-tests/csharp/NUnit.TestProject/NUnit.Project.csproj b/docs/core/testing/snippets/order-unit-tests/csharp/NUnit.TestProject/NUnit.Project.csproj index bbb21b1fdc348..484ac5c4f5e6d 100644 --- a/docs/core/testing/snippets/order-unit-tests/csharp/NUnit.TestProject/NUnit.Project.csproj +++ b/docs/core/testing/snippets/order-unit-tests/csharp/NUnit.TestProject/NUnit.Project.csproj @@ -11,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/docs/core/testing/snippets/unit-testing-using-mstest/csharp/PrimeService.Tests/PrimeService.Tests.csproj b/docs/core/testing/snippets/unit-testing-using-mstest/csharp/PrimeService.Tests/PrimeService.Tests.csproj index d292715fb10ef..b45795bef0eb0 100644 --- a/docs/core/testing/snippets/unit-testing-using-mstest/csharp/PrimeService.Tests/PrimeService.Tests.csproj +++ b/docs/core/testing/snippets/unit-testing-using-mstest/csharp/PrimeService.Tests/PrimeService.Tests.csproj @@ -8,8 +8,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/docs/core/tutorials/snippets/library-with-visual-studio-6-0/csharp/StringLibraryTest/StringLibraryTest.csproj b/docs/core/tutorials/snippets/library-with-visual-studio-6-0/csharp/StringLibraryTest/StringLibraryTest.csproj index 5cfa932b52624..6ae3b3d1f7cf5 100644 --- a/docs/core/tutorials/snippets/library-with-visual-studio-6-0/csharp/StringLibraryTest/StringLibraryTest.csproj +++ b/docs/core/tutorials/snippets/library-with-visual-studio-6-0/csharp/StringLibraryTest/StringLibraryTest.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/docs/core/tutorials/snippets/library-with-visual-studio/csharp/StringLibraryTest/StringLibraryTest.csproj b/docs/core/tutorials/snippets/library-with-visual-studio/csharp/StringLibraryTest/StringLibraryTest.csproj index 5ed6c796bfe2c..bc57658fa0486 100644 --- a/docs/core/tutorials/snippets/library-with-visual-studio/csharp/StringLibraryTest/StringLibraryTest.csproj +++ b/docs/core/tutorials/snippets/library-with-visual-studio/csharp/StringLibraryTest/StringLibraryTest.csproj @@ -7,7 +7,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/docs/core/tutorials/snippets/library-with-visual-studio/csharp/StringLibraryTestNet8/StringLibraryTest.csproj b/docs/core/tutorials/snippets/library-with-visual-studio/csharp/StringLibraryTestNet8/StringLibraryTest.csproj index df06c2a8038bc..9cb6f820e71f6 100644 --- a/docs/core/tutorials/snippets/library-with-visual-studio/csharp/StringLibraryTestNet8/StringLibraryTest.csproj +++ b/docs/core/tutorials/snippets/library-with-visual-studio/csharp/StringLibraryTestNet8/StringLibraryTest.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/docs/core/tutorials/snippets/library-with-visual-studio/vb/StringLibraryTest/StringLibraryTest.vbproj b/docs/core/tutorials/snippets/library-with-visual-studio/vb/StringLibraryTest/StringLibraryTest.vbproj index 344ea59194d57..6446345649c47 100644 --- a/docs/core/tutorials/snippets/library-with-visual-studio/vb/StringLibraryTest/StringLibraryTest.vbproj +++ b/docs/core/tutorials/snippets/library-with-visual-studio/vb/StringLibraryTest/StringLibraryTest.vbproj @@ -8,8 +8,8 @@ - - + + diff --git a/docs/core/whats-new/snippets/dotnet-8/csharp/ConsoleApp/Project.csproj b/docs/core/whats-new/snippets/dotnet-8/csharp/ConsoleApp/Project.csproj index 50719562332f2..55dff7630a4c5 100644 --- a/docs/core/whats-new/snippets/dotnet-8/csharp/ConsoleApp/Project.csproj +++ b/docs/core/whats-new/snippets/dotnet-8/csharp/ConsoleApp/Project.csproj @@ -9,10 +9,10 @@ - + - + diff --git a/docs/csharp/language-reference/compiler-messages/snippets/null-warnings/null-warnings.csproj b/docs/csharp/language-reference/compiler-messages/snippets/null-warnings/null-warnings.csproj index 911bdbd407a2b..9ab150041bb95 100644 --- a/docs/csharp/language-reference/compiler-messages/snippets/null-warnings/null-warnings.csproj +++ b/docs/csharp/language-reference/compiler-messages/snippets/null-warnings/null-warnings.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/csharp/language-reference/keywords/partial-type.md b/docs/csharp/language-reference/keywords/partial-type.md index 04caed825fc4a..93ba159eb7bfb 100644 --- a/docs/csharp/language-reference/keywords/partial-type.md +++ b/docs/csharp/language-reference/keywords/partial-type.md @@ -11,7 +11,7 @@ ms.assetid: 27320743-a22e-4c7b-b0b3-53afe3607334 --- # partial type (C# Reference) -Partial type definitions allow for the definition of a class, struct, interface, or record to be split into multiple files. +Partial type definitions allow for the definition of a class, struct, interface, or record to be split into multiple definitions that can be in different files in the same project. In *File1.cs*: diff --git a/docs/csharp/language-reference/operators/snippets/shared/operators.csproj b/docs/csharp/language-reference/operators/snippets/shared/operators.csproj index e6e14c8c9d514..ae3bcd98d8d31 100644 --- a/docs/csharp/language-reference/operators/snippets/shared/operators.csproj +++ b/docs/csharp/language-reference/operators/snippets/shared/operators.csproj @@ -10,7 +10,7 @@ - + diff --git a/docs/csharp/roslyn-sdk/tutorials/snippets/how-to-write-csharp-analyzer-code-fix/MakeConst/MakeConst.Test/MakeConst.Test.csproj b/docs/csharp/roslyn-sdk/tutorials/snippets/how-to-write-csharp-analyzer-code-fix/MakeConst/MakeConst.Test/MakeConst.Test.csproj index 3ec358c45b6be..ac71c1f1ebe81 100644 --- a/docs/csharp/roslyn-sdk/tutorials/snippets/how-to-write-csharp-analyzer-code-fix/MakeConst/MakeConst.Test/MakeConst.Test.csproj +++ b/docs/csharp/roslyn-sdk/tutorials/snippets/how-to-write-csharp-analyzer-code-fix/MakeConst/MakeConst.Test/MakeConst.Test.csproj @@ -9,8 +9,8 @@ - - + + diff --git a/docs/csharp/roslyn-sdk/tutorials/snippets/how-to-write-csharp-analyzer-code-fix/MakeConst/MakeConst.Vsix/MakeConst.Vsix.csproj b/docs/csharp/roslyn-sdk/tutorials/snippets/how-to-write-csharp-analyzer-code-fix/MakeConst/MakeConst.Vsix/MakeConst.Vsix.csproj index b09bac3788b62..209e2ceff6a89 100644 --- a/docs/csharp/roslyn-sdk/tutorials/snippets/how-to-write-csharp-analyzer-code-fix/MakeConst/MakeConst.Vsix/MakeConst.Vsix.csproj +++ b/docs/csharp/roslyn-sdk/tutorials/snippets/how-to-write-csharp-analyzer-code-fix/MakeConst/MakeConst.Vsix/MakeConst.Vsix.csproj @@ -24,7 +24,7 @@ - + diff --git a/docs/fundamentals/networking/http/httpclient.md b/docs/fundamentals/networking/http/httpclient.md index b024f58f882b6..da158c963409b 100644 --- a/docs/fundamentals/networking/http/httpclient.md +++ b/docs/fundamentals/networking/http/httpclient.md @@ -62,6 +62,19 @@ To make an HTTP request, you call any of the following APIs: > [!WARNING] > Making HTTP requests is considered network I/O-bound work. While there is a synchronous method, it is recommended to use the asynchronous APIs instead, unless you have good reason not to. +> [!NOTE] +> While targeting Android devices (such as with .NET MAUI development), you must add `android:usesCleartextTraffic="true"` to `` in _AndroidManifest.xml_. This enables clear-text traffic, such as HTTP requests, which is otherwise disabled by default due to Android security policies. Consider the following example XML settings: +> +> ```xml +> +> +> +> +> +> ``` +> +> For more information, see [Enable clear-text network traffic for the localhost domain](/dotnet/maui/data-cloud/local-web-services?view=net-maui-8.0#enable-clear-text-network-traffic-for-the-localhost-domain). + ### HTTP content The type is used to represent an HTTP entity body and corresponding content headers. For HTTP methods (or request methods) that require a body, `POST`, `PUT`, and `PATCH`, you use the class to specify the body of the request. Most examples show how to prepare the subclass with a JSON payload, but other subclasses exist for different [content (MIME) types](https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/MIME_types). diff --git a/docs/fundamentals/networking/telemetry/snippets/metrics/HelloBuiltinMetrics.csproj b/docs/fundamentals/networking/telemetry/snippets/metrics/HelloBuiltinMetrics.csproj index 2cd8de31c683f..dbd17a2559533 100644 --- a/docs/fundamentals/networking/telemetry/snippets/metrics/HelloBuiltinMetrics.csproj +++ b/docs/fundamentals/networking/telemetry/snippets/metrics/HelloBuiltinMetrics.csproj @@ -11,7 +11,7 @@ - + diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Resources/ResourceReader/Overview/csharp/Project.csproj b/docs/fundamentals/runtime-libraries/snippets/System.Resources/ResourceReader/Overview/csharp/Project.csproj index 14db93c5853aa..c60cee935224e 100644 --- a/docs/fundamentals/runtime-libraries/snippets/System.Resources/ResourceReader/Overview/csharp/Project.csproj +++ b/docs/fundamentals/runtime-libraries/snippets/System.Resources/ResourceReader/Overview/csharp/Project.csproj @@ -6,7 +6,7 @@ - + diff --git a/docs/orleans/deployment/snippets/service-fabric/stateless/Orleans.ServiceFabric.Stateless.csproj b/docs/orleans/deployment/snippets/service-fabric/stateless/Orleans.ServiceFabric.Stateless.csproj index f2893e96d4d0e..5c895fbf8efa6 100644 --- a/docs/orleans/deployment/snippets/service-fabric/stateless/Orleans.ServiceFabric.Stateless.csproj +++ b/docs/orleans/deployment/snippets/service-fabric/stateless/Orleans.ServiceFabric.Stateless.csproj @@ -13,7 +13,7 @@ - + diff --git a/samples/snippets/core/testing/unit-testing-using-nunit/csharp/PrimeService.Tests/PrimeService.Tests.csproj b/samples/snippets/core/testing/unit-testing-using-nunit/csharp/PrimeService.Tests/PrimeService.Tests.csproj index ac2aedf77bf2f..f7875c7a57cd8 100644 --- a/samples/snippets/core/testing/unit-testing-using-nunit/csharp/PrimeService.Tests/PrimeService.Tests.csproj +++ b/samples/snippets/core/testing/unit-testing-using-nunit/csharp/PrimeService.Tests/PrimeService.Tests.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/samples/snippets/core/testing/unit-testing-vb-mstest/vb/PrimeService.Tests/PrimeService.Tests.vbproj b/samples/snippets/core/testing/unit-testing-vb-mstest/vb/PrimeService.Tests/PrimeService.Tests.vbproj index 87da4b72efe6a..9fa6fad347091 100644 --- a/samples/snippets/core/testing/unit-testing-vb-mstest/vb/PrimeService.Tests/PrimeService.Tests.vbproj +++ b/samples/snippets/core/testing/unit-testing-vb-mstest/vb/PrimeService.Tests/PrimeService.Tests.vbproj @@ -8,8 +8,8 @@ - - + + diff --git a/samples/snippets/standard/data/sqlite/AggregateFunctionSample/AggregateFunctionSample.csproj b/samples/snippets/standard/data/sqlite/AggregateFunctionSample/AggregateFunctionSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/AggregateFunctionSample/AggregateFunctionSample.csproj +++ b/samples/snippets/standard/data/sqlite/AggregateFunctionSample/AggregateFunctionSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/AsyncSample/AsyncSample.csproj b/samples/snippets/standard/data/sqlite/AsyncSample/AsyncSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/AsyncSample/AsyncSample.csproj +++ b/samples/snippets/standard/data/sqlite/AsyncSample/AsyncSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/BackupSample/BackupSample.csproj b/samples/snippets/standard/data/sqlite/BackupSample/BackupSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/BackupSample/BackupSample.csproj +++ b/samples/snippets/standard/data/sqlite/BackupSample/BackupSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/BatchingSample/BatchingSample.csproj b/samples/snippets/standard/data/sqlite/BatchingSample/BatchingSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/BatchingSample/BatchingSample.csproj +++ b/samples/snippets/standard/data/sqlite/BatchingSample/BatchingSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/BulkInsertSample/BulkInsertSample.csproj b/samples/snippets/standard/data/sqlite/BulkInsertSample/BulkInsertSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/BulkInsertSample/BulkInsertSample.csproj +++ b/samples/snippets/standard/data/sqlite/BulkInsertSample/BulkInsertSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/CollationSample/CollationSample.csproj b/samples/snippets/standard/data/sqlite/CollationSample/CollationSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/CollationSample/CollationSample.csproj +++ b/samples/snippets/standard/data/sqlite/CollationSample/CollationSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/DapperSample/DapperSample.csproj b/samples/snippets/standard/data/sqlite/DapperSample/DapperSample.csproj index 714cfc21d7460..78128be340b66 100644 --- a/samples/snippets/standard/data/sqlite/DapperSample/DapperSample.csproj +++ b/samples/snippets/standard/data/sqlite/DapperSample/DapperSample.csproj @@ -8,7 +8,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/DateAndTimeSample/DateAndTimeSample.csproj b/samples/snippets/standard/data/sqlite/DateAndTimeSample/DateAndTimeSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/DateAndTimeSample/DateAndTimeSample.csproj +++ b/samples/snippets/standard/data/sqlite/DateAndTimeSample/DateAndTimeSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/DeferredTransactionSample/DeferredTransactionSample.csproj b/samples/snippets/standard/data/sqlite/DeferredTransactionSample/DeferredTransactionSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/DeferredTransactionSample/DeferredTransactionSample.csproj +++ b/samples/snippets/standard/data/sqlite/DeferredTransactionSample/DeferredTransactionSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/DirtyReadSample/DirtyReadSample.csproj b/samples/snippets/standard/data/sqlite/DirtyReadSample/DirtyReadSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/DirtyReadSample/DirtyReadSample.csproj +++ b/samples/snippets/standard/data/sqlite/DirtyReadSample/DirtyReadSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/EncryptionSample/EncryptionSample.csproj b/samples/snippets/standard/data/sqlite/EncryptionSample/EncryptionSample.csproj index fefb7d426f4b0..94dd3b560d747 100644 --- a/samples/snippets/standard/data/sqlite/EncryptionSample/EncryptionSample.csproj +++ b/samples/snippets/standard/data/sqlite/EncryptionSample/EncryptionSample.csproj @@ -7,8 +7,8 @@ - - + + diff --git a/samples/snippets/standard/data/sqlite/ExtensionsSample/ExtensionsSample.csproj b/samples/snippets/standard/data/sqlite/ExtensionsSample/ExtensionsSample.csproj index fbe9febcc65d8..076d94e540167 100644 --- a/samples/snippets/standard/data/sqlite/ExtensionsSample/ExtensionsSample.csproj +++ b/samples/snippets/standard/data/sqlite/ExtensionsSample/ExtensionsSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/HelloWorldSample/HelloWorldSample.csproj b/samples/snippets/standard/data/sqlite/HelloWorldSample/HelloWorldSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/HelloWorldSample/HelloWorldSample.csproj +++ b/samples/snippets/standard/data/sqlite/HelloWorldSample/HelloWorldSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/InteropSample/InteropSample.csproj b/samples/snippets/standard/data/sqlite/InteropSample/InteropSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/InteropSample/InteropSample.csproj +++ b/samples/snippets/standard/data/sqlite/InteropSample/InteropSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/RegularExpressionSample/RegularExpressionSample.csproj b/samples/snippets/standard/data/sqlite/RegularExpressionSample/RegularExpressionSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/RegularExpressionSample/RegularExpressionSample.csproj +++ b/samples/snippets/standard/data/sqlite/RegularExpressionSample/RegularExpressionSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/ResultMetadataSample/ResultMetadataSample.csproj b/samples/snippets/standard/data/sqlite/ResultMetadataSample/ResultMetadataSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/ResultMetadataSample/ResultMetadataSample.csproj +++ b/samples/snippets/standard/data/sqlite/ResultMetadataSample/ResultMetadataSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/SavepointSample/SavepointSample.csproj b/samples/snippets/standard/data/sqlite/SavepointSample/SavepointSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/SavepointSample/SavepointSample.csproj +++ b/samples/snippets/standard/data/sqlite/SavepointSample/SavepointSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/ScalarFunctionSample/ScalarFunctionSample.csproj b/samples/snippets/standard/data/sqlite/ScalarFunctionSample/ScalarFunctionSample.csproj index 5d8ef36c4b03f..032d93e584b0d 100644 --- a/samples/snippets/standard/data/sqlite/ScalarFunctionSample/ScalarFunctionSample.csproj +++ b/samples/snippets/standard/data/sqlite/ScalarFunctionSample/ScalarFunctionSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/SqliteProviderSample/SqliteProviderSample.csproj b/samples/snippets/standard/data/sqlite/SqliteProviderSample/SqliteProviderSample.csproj index c28c463c1349a..0ee83ea964c71 100644 --- a/samples/snippets/standard/data/sqlite/SqliteProviderSample/SqliteProviderSample.csproj +++ b/samples/snippets/standard/data/sqlite/SqliteProviderSample/SqliteProviderSample.csproj @@ -7,9 +7,9 @@ - - - + + + diff --git a/samples/snippets/standard/data/sqlite/StreamingSample/StreamingSample.csproj b/samples/snippets/standard/data/sqlite/StreamingSample/StreamingSample.csproj index 347c973c35d22..630fac4b0e4e7 100644 --- a/samples/snippets/standard/data/sqlite/StreamingSample/StreamingSample.csproj +++ b/samples/snippets/standard/data/sqlite/StreamingSample/StreamingSample.csproj @@ -7,7 +7,7 @@ - + diff --git a/samples/snippets/standard/data/sqlite/SystemLibrarySample/SystemLibrarySample.csproj b/samples/snippets/standard/data/sqlite/SystemLibrarySample/SystemLibrarySample.csproj index ce06583f527b7..48c32528df71b 100644 --- a/samples/snippets/standard/data/sqlite/SystemLibrarySample/SystemLibrarySample.csproj +++ b/samples/snippets/standard/data/sqlite/SystemLibrarySample/SystemLibrarySample.csproj @@ -7,8 +7,8 @@ - - + +