-
Notifications
You must be signed in to change notification settings - Fork 6.1k
User-assigned identity flow #44718
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
alexwolfmsft
merged 23 commits into
dotnet:main
from
alexwolfmsft:user-assigned-identity-flow
Feb 10, 2025
Merged
User-assigned identity flow #44718
Changes from 11 commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
1d42c61
User-assigned identity flow
alexwolfmsft 9991dbe
fix redirects
alexwolfmsft 12bdf31
fix trailing line
alexwolfmsft aa57015
fix tabs
alexwolfmsft 7519517
client id
alexwolfmsft 1ccab5e
updates
alexwolfmsft 685b14a
updates
alexwolfmsft 0892a62
command links
alexwolfmsft 4b2b9a0
fixes
alexwolfmsft ea28e6b
clean up
alexwolfmsft 15bc84b
fix
alexwolfmsft 1c5ec51
Apply suggestions from code review
alexwolfmsft b111def
Apply suggestions from code review
alexwolfmsft d692666
Apply suggestions from code review
alexwolfmsft 002bce8
fix link
alexwolfmsft db1c851
fix link
alexwolfmsft eea2aff
update include content
alexwolfmsft 8bcf201
Apply suggestions from code review
alexwolfmsft dc05106
simplify ID list
alexwolfmsft e24a5e1
PR fixes
alexwolfmsft b5e700c
Apply suggestions from code review
alexwolfmsft 80e361c
fixes
alexwolfmsft af31b9f
Merge branch 'user-assigned-identity-flow' of https://github.com/alex…
alexwolfmsft File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 6 additions & 6 deletions
12
...e/sdk/authentication/azure-hosted-apps.md → ...ation/system-assigned-managed-identity.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
200 changes: 200 additions & 0 deletions
200
docs/azure/sdk/authentication/user-assigned-managed-identity.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,200 @@ | ||
| --- | ||
| title: Authenticate Azure-hosted .NET apps to Azure resources using a user-assigned managed identity | ||
| description: Learn how to authenticate Azure-hosted .NET apps to other Azure services using a user-assigned identity | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ms.topic: how-to | ||
| ms.custom: devx-track-dotnet, engagement-fy23, devx-track-azurecli | ||
| ms.date: 02/06/2025 | ||
| --- | ||
|
|
||
| # Authenticate Azure-hosted .NET apps to Azure resources using a user-assigned managed identity | ||
|
|
||
| The recommended approach to authenticate an Azure-hosted app to other Azure resources is to use a [managed identity](/entra/identity/managed-identities-azure-resources/overview). This approach is [supported for most Azure services](/entra/identity/managed-identities-azure-resources/managed-identities-status), including apps hosted on Azure App Service, Azure Container Apps, and Azure Virtual Machines. Discover more about different authentication techniques and approaches on the [authentication overview](/dotnet/azure/sdk/authentication) page. In the sections ahead, you'll learn: | ||
|
|
||
| - Essential managed identity concepts | ||
| - How to create a user-assigned managed identity for your app | ||
| - How to assign roles to the user-assigned managed identity | ||
| - How to authenticate using the user-assigned managed identity from your app code | ||
|
|
||
| [!INCLUDE [managed-identity-concepts](../includes/managed-identity-concepts.md)] | ||
|
|
||
| ## Create a user-assigned managed identity | ||
|
|
||
| User-assigned identities are created as standalone resources in your Azure subscription using the Azure portal or the Azure CLI. Azure CLI commands can be run in the [Azure Cloud Shell](https://shell.azure.com) or on a workstation with the [Azure CLI installed](/cli/azure/install-azure-cli). | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### [Azure portal](#tab/azure-portal) | ||
|
|
||
| 1. In the Azure portal, enter *Managed identities* in the main search bar and select the matching result under the **Services** section. | ||
| 1. On the **Managed Identities** page, select **+ Create**. | ||
|
|
||
| :::image type="content" source="../media/user-assigned-identity-create.png" alt-text="A screenshot showing the page to manage user-assigned identities."::: | ||
|
|
||
| 1. On the **Create User Assigned Managed Identity** page, select a subscription, resource group, and region for the user-assigned identity, and then provide a name. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 1. Select **Review + create** to review and validate your inputs. | ||
|
|
||
| :::image type="content" source="../media/user-assigned-identity-form.png" alt-text="A screenshot showing the form to create a user-assigned identity."::: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| 1. Select **Create** to create the user-assigned identity. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 1. After the identity is created, select **Go to resource**. | ||
| 1. On the new identity's **Overview** page, copy the `Client ID` value to use for later when you configure the application code. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### [Azure CLI](#tab/azure-cli) | ||
|
|
||
| Use the Azure CLI command [`az identity create`](/cli/azure/identity?view=azure-cli-latest#az-identity-create) to create a managed identity: | ||
|
|
||
| ```azurecli | ||
| az identity create --resource-group <resource-group-name> --name <identity-name> | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| The command output prints the following values: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| - **ClientID**: Used to configure application code that uses the identity. | ||
| - **Location**: The Azure region that contains the identity. | ||
| - **Name**: The name of the identity. | ||
| - **PrincipalId**: Used for access control and role assignments in Azure. | ||
| - **ResourceGroup**: The resource group that contains the identity. | ||
| - **TenantId**: The Microsoft Entra tenant that contains the identity. | ||
|
|
||
| You can always view the managed identity properties again using the [`az identity show`](/cli/azure/identity?view=azure-cli-latest#az-identity-show) command: | ||
|
|
||
| ```azurecli | ||
| az identity show \ | ||
| --resource-group <your-resource-group> \ | ||
| --name <your-managed-identity-name> \ | ||
| -o json | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Assign the managed identity to your app | ||
|
|
||
| A user-assigned can be associated with one or more Azure resources. All of the resources that use that identity gain the permissions applied through the identity's roles. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### [Azure portal](#tab/azure-portal) | ||
|
|
||
| 1. In the Azure portal, navigate to the resource that hosts your app code, such as an Azure App Service or Azure Container App instance. | ||
| 1. From the resource's **Overview** page, expand **Settings** and select **Identity** from the navigation. | ||
| 1. On the **Identity** page, switch to the **User assigned** tab. | ||
| 1. Select **+ Add** to open the **Add user assigned managed identity** panel. | ||
| 1. On the **Add user assigned managed identity** panel, use the **Subscription** dropdown to filter the search results for your identities. Use the **User assigned managed identities** search box to locate the user-assigned managed identity you enabled for the Azure resource hosting your app. | ||
| 1. Select the identity and choose **Add** at the bottom of the panel to continue. | ||
|
|
||
| :::image type="content" source="../media/add-user-assigned-identity-to-app.png" alt-text="A screenshot showing how to associate a user-assigned identity with an app."::: | ||
|
|
||
| ### [Azure CLI](#tab/azure-cli) | ||
|
|
||
| The Azure CLI provides different commands to assign a user-assigned identity to different types of hosting services. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| To assign a user-assigned identity to a resource such as an Azure App Service web app using the Azure CLI, you'll need the resource ID of the identity. Use the [`az identity show`](/cli/azure/identity?view=azure-cli-latest#az-identity-show) command to retrieve the resource ID: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```azurecli | ||
| az identity show \ | ||
| --resource-group <your-resource-group> \ | ||
| --name <your-managed-identity-name> \ | ||
| -o json --query id | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| Once you have the resource ID, use the Azure CLI command `az <resourceType> identity assign` command to associate the user-assigned identity with different resources, such as the following: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| For Azure App Service, use the Azure CLI command [`az webapp identity assign`](/cli/azure/webapp/identity?view=azure-cli-latest#az-webapp-identity-assign): | ||
|
|
||
| ```azurecli | ||
| az webapp identity assign \ | ||
| --resource-group <resource-group-name> \ | ||
| --name <webapp-name> \ | ||
| --identities <user-assigned-identity-resource-id> | ||
| ``` | ||
|
|
||
| For Azure Container Apps, use the Azure CLI command [`az containerapp identity assign`](/cli/azure/containerapp/identity?view=azure-cli-latest#az-containerapp-identity-assign): | ||
|
|
||
| ```azurecli | ||
| az webapp identity assign \ | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| --resource-group <resource-group-name> \ | ||
| --name <webapp-name> \ | ||
| --identities <user-assigned-identity-resource-id> | ||
| ``` | ||
|
|
||
| For Azure Virtual Machines, use the Azure CLI command [`az vm identity assign`](/cli/azure/vm/identity?view=azure-cli-latest#az-vm-identity-assign): | ||
|
|
||
| ```azurecli | ||
| az vm identity assign \ | ||
| --resource-group <resource-group-name> \ | ||
| --name <webapp-name> \ | ||
| --identities <user-assigned-identity-resource-id> | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Assign roles to the managed identity | ||
|
|
||
| Next, determine which roles your app needs and assign those roles to the managed identity. You can assign roles to a managed identity at the following scopes: | ||
|
|
||
| - **Resource**: The assigned roles only apply to that specific resource. | ||
| - **Resource group**: The assigned roles apply to all resources contained in the resource group. | ||
| - **Subscription**: The assigned roles apply to all resources contained in the subscription. | ||
|
|
||
| The following example shows how to assign roles at the resource group scope, since many apps manage all their related Azure resources using a single resource group. | ||
|
|
||
| ### [Azure portal](#tab/azure-portal) | ||
|
|
||
| 1. Navigate to the **Overview** page of the resource group that contains the app with the user-assigned managed identity. | ||
| 1. Select **Access control (IAM)** on the left navigation. | ||
| 1. On the **Access control (IAM)** page, select **+ Add** on the top menu and then choose **Add role assignment** to navigate to the **Add role assignment** page. | ||
|
|
||
| :::image type="content" source="../media/add-role-assignment.png" alt-text="A screenshot showing how to access the identity role assignment page."::: | ||
|
|
||
| 1. The **Add role assignment** page presents a tabbed, multi-step workflow to assign roles to identities. On the initial **Role** tab, use the search box at the top to locate the role you want to assign to the identity. | ||
| 1. Select the role from the results and then choose **Next** to move to the **Members** tab. | ||
| 1. For the **Assign access to** option, select **Managed identity**. | ||
| 1. For the **Members** option, choose **+ Select members** to open the **Select managed identities** panel. | ||
| 1. On the **Select managed identities** panel, use the **Subscription** and **Managed identity** dropdowns to filter the search results for your identities. Use the **Select** search box to locate the user-assigned managed identity you enabled for the Azure resource hosting your app. | ||
|
|
||
| :::image type="content" source="../media/user-assigned-identity-assign-roles.png" alt-text="A screenshot showing the managed identity assignment process."::: | ||
|
|
||
| 1. Select the identity and choose **Select** at the bottom of the panel to continue. | ||
| 1. Select **Review + assign** at the bottom of the page. | ||
| 1. On the final **Review + assign** tab, select **Review + assign** to complete the workflow. | ||
|
|
||
| ### [Azure CLI](#tab/azure-cli) | ||
|
|
||
| To assign a role to a user-assigned identity using the Azure CLI, you'll need the principal ID of the identity. Use the `az identity show` command to retrieve the resource ID: | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```azurecli | ||
| az identity show \ | ||
| --resource-group <your-resource-group> \ | ||
| --name <your-managed-identity-name> \ | ||
| -o json --query principalId | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| Assign a role to a managed identity using the [az role assignment create](/cli/azure/role/assignment#az-role-assignment-create) command: | ||
|
|
||
| ```azurecli | ||
| az role assignment create \ | ||
| --assignee <your-principal-id> \ | ||
| --role <role-name> \ | ||
| --scope <scope> | ||
| ``` | ||
|
|
||
| To explore which roles a managed identity can be assigned, use the [az role definition list](/cli/azure/role/definition#az-role-definition-list) command: | ||
|
|
||
| ```azurecli | ||
| az role definition list \ | ||
| --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \ | ||
| --output table | ||
| ``` | ||
|
|
||
| For example, to allow the managed identity with the ID of `99999999-9999-9999-9999-999999999999` read, write, and delete access to Azure Storage blob containers and data to all storage accounts in the *msdocs-dotnet-sdk-auth-example* resource group, assign the application service principal to the *Storage Blob Data Contributor* role using the following command: | ||
|
|
||
| ```azurecli | ||
| az role assignment create \ | ||
| --assignee 99999999-9999-9999-9999-999999999999 \ | ||
| --role "Storage Blob Data Contributor" \ | ||
| --scope "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/msdocs-dotnet-sdk-auth-example" | ||
| ``` | ||
|
|
||
| For information on assigning permissions at the resource or subscription level using the Azure CLI, see the article [Assign Azure roles using the Azure CLI](/azure/role-based-access-control/role-assignments-cli). | ||
|
|
||
| --- | ||
|
|
||
| ## Implement DefaultAzureCredential in your application | ||
|
|
||
| [!INCLUDE [Implement DefaultAzureCredential](<../includes/implement-user-assigned-identity.md>)] | ||
69 changes: 69 additions & 0 deletions
69
docs/azure/sdk/includes/implement-user-assigned-identity.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| --- | ||
| ms.topic: include | ||
| ms.date: 08/15/2024 | ||
| --- | ||
| [DefaultAzureCredential](../authentication/credential-chains.md#defaultazurecredential-overview) is an opinionated, ordered sequence of mechanisms for authenticating to Microsoft Entra ID. Each authentication mechanism is a class derived from the [TokenCredential](/dotnet/api/azure.core.tokencredential?view=azure-dotnet&preserve-view=true) class and is known as a *credential*. At runtime, `DefaultAzureCredential` attempts to authenticate using the 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. In this way, your app can use different credentials in different environments without writing environment-specific code. | ||
|
|
||
| To use `DefaultAzureCredential`, add the [Azure.Identity](/dotnet/api/azure.identity) and optionally the [Microsoft.Extensions.Azure](/dotnet/api/microsoft.extensions.azure) packages to your application: | ||
|
|
||
| ### [Command Line](#tab/command-line) | ||
|
|
||
| In a terminal of your choice, navigate to the application project directory and run the following commands: | ||
|
|
||
| ```dotnetcli | ||
| dotnet add package Azure.Identity | ||
| dotnet add package Microsoft.Extensions.Azure | ||
| ``` | ||
|
|
||
| ### [NuGet Package Manager](#tab/nuget-package) | ||
|
|
||
| Right-click your project in Visual Studio's **Solution Explorer** window and select **Manage NuGet Packages**. Search for **Azure.Identity**, and install the matching package. Repeat this process for the **Microsoft.Extensions.Azure** package. | ||
|
|
||
| :::image type="content" source="../media/nuget-azure-identity.png" alt-text="Install a package using the package manager."::: | ||
|
|
||
| --- | ||
|
|
||
| Azure services are accessed using specialized client classes from the various Azure SDK client libraries. These classes and your own custom services should be registered so they can be accessed via dependency injection throughout your app. In `Program.cs`, complete the following steps to register a client class and `DefaultAzureCredential`: | ||
|
|
||
| 1. Include the `Azure.Identity` and `Microsoft.Extensions.Azure` namespaces via `using` directives. | ||
| 1. Register the Azure service client using the corresponding `Add`-prefixed extension method. | ||
| 1. Pass an instance of `DefaultAzureCredential` to the `UseCredential` method. | ||
|
|
||
| > [!NOTE] | ||
| > For a user-assigned managed identity, make sure to assign the identity's `clientId` value to the `ManagedIdentityClientId` property on the `DefaultAzureCredentialOptions` object. This enables your code to discover the correct identity to use for authentication while running in azure. | ||
|
|
||
| For example: | ||
|
|
||
| ```c# | ||
| using Microsoft.Extensions.Azure; | ||
| using Azure.Identity; | ||
|
|
||
| builder.Services.AddAzureClients(clientBuilder => | ||
| { | ||
| clientBuilder.AddBlobServiceClient( | ||
| new Uri("https://<account-name>.blob.core.windows.net")); | ||
| clientBuilder.UseCredential(new DefaultAzureCredential( | ||
| new DefaultAzureCredentialOptions() | ||
| { | ||
| ManagedIdentityClientId = "<your-client-id>" | ||
| })); | ||
| }); | ||
| ``` | ||
|
|
||
| An alternative to `UseCredential` is to instantiate `DefaultAzureCredential` directly: | ||
|
|
||
| ```c# | ||
| using Azure.Identity; | ||
|
|
||
| builder.Services.AddSingleton<BlobServiceClient>(_ => | ||
| new BlobServiceClient( | ||
| new Uri("https://<account-name>.blob.core.windows.net"), | ||
| new DefaultAzureCredential(new DefaultAzureCredentialOptions() | ||
| { | ||
| ManagedIdentityClientId = "<your-client-id>" | ||
| }))); | ||
| ``` | ||
|
|
||
| When the preceding code runs on your local development workstation, `DefaultAzureCredential` looks in the environment variables for an application service principal or at locally installed developer tools, such as Visual Studio, for a set of developer credentials. Either approach can be used to authenticate the app to Azure resources during local development. | ||
|
|
||
| When deployed to Azure, this same code can also authenticate your app to other Azure resources. `DefaultAzureCredential` can retrieve environment settings and managed identity configurations to authenticate to other services automatically. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| ## Essential managed identity concepts | ||
|
|
||
| A managed identity enables your app to securely connect to other Azure resources without the use of secret keys or other application secrets. Internally, Azure tracks the identity and which resources it's allowed to connect to. Azure uses this information to automatically obtain Microsoft Entra tokens for the app to allow it to connect to other Azure resources. | ||
alexwolfmsft marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| There are two types of managed identities to consider when configuring your hosted app: | ||
|
|
||
| - **System-assigned** identities are enabled directly on an Azure resource and are tied to its life cycle. When the resource is deleted, Azure automatically deletes the identity for you. System-assigned identities provide a minimalistic approach to using managed identities. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| - **User-assigned** identities are created as standalone Azure resources and offer greater flexibility and capabilities. They are ideal for solutions involving multiple Azure resources that need to share the same identity and permissions. For example, if multiple virtual machines need to access the same set of Azure resources, a user-assigned managed identity provides reusability and optimized management. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| The sections ahead describe the steps to enable and use a user-assigned managed identity for an Azure-hosted app. If you need to use a user-assigned managed identity, visit the [system-assigned managed identities](/system-assigned-identity-auth) article for more information. | ||
alexwolfmsft marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.