diff --git a/docs/azure/media/group-role-assignment.png b/docs/azure/media/group-role-assignment.png new file mode 100644 index 0000000000000..b684b45960d83 Binary files /dev/null and b/docs/azure/media/group-role-assignment.png differ diff --git a/docs/azure/sdk/authentication/local-development-service-principal.md b/docs/azure/sdk/authentication/local-development-service-principal.md index 1654c86a90410..7bf16926d7f43 100644 --- a/docs/azure/sdk/authentication/local-development-service-principal.md +++ b/docs/azure/sdk/authentication/local-development-service-principal.md @@ -3,7 +3,7 @@ title: Authenticate .NET apps to Azure services during local development using s description: Learn how to authenticate your app to Azure services during local development using dedicated application service principals. ms.topic: how-to ms.custom: devx-track-dotnet, engagement-fy23, devx-track-azurecli -ms.date: 03/04/2025 +ms.date: 03/11/2025 --- # Authenticate .NET apps to Azure services during local development using service principals @@ -26,252 +26,12 @@ When the app is registered in Azure, an application service principal is created During local development, environment variables are set with the application service principal's identity. The Azure Identity library reads these environment variables to authenticate the app to the required Azure resources. -## Register the app in Azure +[!INCLUDE [create-app-registration](../includes/auth-create-app-registration.md)] -Application service principal objects are created through an app registration in Azure using either the Azure portal or Azure CLI. +[!INCLUDE [create-entra-group](../includes/auth-create-entra-group.md)] -### [Azure portal](#tab/azure-portal) +[!INCLUDE [auth-assign-group-roles](../includes/auth-assign-group-roles.md)] -1. In the Azure portal, use the search bar to navigate to the **App registrations** page. -1. On the **App registrations** page, select **+ New registration**. -1. On the **Register an application** page: - - For the **Name** field, enter a descriptive value that includes the app name and the target environment. - - For the **Supported account types**, select **Accounts in this organizational directory only (Microsoft Customer Led only - Single tenant)**, or whichever option best fits your requirements. -1. Select **Register** to register your app and create the service principal. - - :::image type="content" source="../../media/app-registration.png" alt-text="A screenshot showing how to create an app registration in the Azure portal."::: - -1. On the **App registration** page for your app, copy the **Application (client) ID** and **Directory (tenant) ID** and paste them in a temporary location for later use in your app code configurations. -1. Select **Add a certificate or secret** to set up credentials for your app. -1. On the **Certificates & secrets** page, select **+ New client secret**. -1. In the **Add a client secret** flyout panel that opens: - - For the **Description**, enter a value of Current. - - For the **Expires** value, leave the default recommended value of 180 days. - - Select **Add** to add the secret. -1. On the **Certificates & secrets** page, copy the **Value** property of the client secret for use in a future step. - - > [!NOTE] - > The client secret value is only displayed once after the app registration is created. You can add more client secrets without invalidating this client secret, but there's no way to display this value again. - -### [Azure CLI](#tab/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). - -1. Use the [az ad sp create-for-rbac](/cli/azure/ad/sp#az-ad-sp-create-for-rbac) command to create a new app registration and service principal for the app. - - ```azurecli - az ad sp create-for-rbac --name - ``` - - The output of this command resembles the following JSON: - - ```json - { - "appId": "00000000-0000-0000-0000-000000000000", - "displayName": "", - "password": "abcdefghijklmnopqrstuvwxyz", - "tenant": "11111111-1111-1111-1111-111111111111" - } - ``` - -1. Copy this output into a temporary file in a text editor, as you'll need these values in a future step. - - > [!NOTE] - > The client secret value is only displayed once after the app registration is created. You can add more client secrets without invalidating this client secret, but there's no way to display this value again. - ---- - -## Create a Microsoft Entra group for local development - -Create a Microsoft Entra group to encapsulate the roles (permissions) the app needs in local development rather than assigning the roles to individual service principal objects. This approach offers the following advantages: - -- Every developer has the same roles assigned at the group level. -- If a new role is needed for the app, it only needs to be added to the group for the app. -- If a new developer joins the team, a new application service principal is created for the developer and added to the group, ensuring the developer has the right permissions to work on the app. - -### [Azure portal](#tab/azure-portal) - -1. Navigate to the **Microsoft Entra ID** overview page in the Azure portal. -1. Select **All groups** from the left-hand menu. -1. On the **Groups** page, select **New group**. -1. On the **New group** page, fill out the following form fields: - - **Group type**: Select **Security**. - - **Group name**: Enter a name for the group that includes a reference to the app or environment name. - - **Group description**: Enter a description that explains the purpose of the group. - - :::image type="content" source="../../media/create-group.png" alt-text="A screenshot showing how to create a group in the Azure portal."::: - -1. Select the **No members selected** link under **Members** to add members to the group. -1. In the flyout panel that opens, search for the service principal you created earlier and select it from the filtered results. Choose the **Select** button at the bottom of the panel to confirm your selection. -1. Select **Create** at the bottom of the **New group** page to create the group and return to the **All groups** page. If you don't see the new group listed, wait a moment and refresh the page. - -### [Azure CLI](#tab/azure-cli) - -1. Use the [az ad group create](/cli/azure/ad/group#az-ad-group-create) command to create groups in Microsoft Entra ID. - - ```azurecli - az ad group create \ - --display-name \ - --mail-nickname \ - --description - ``` - - The `--display-name` and `--mail-nickname` parameters are required. The name given to the group should be based on the name and environment of the app to indicate the group's purpose. - -1. To add members to the group, you need the object ID of the application service principal, which is different than the application ID. Use the [az ad sp list](/cli/azure/ad/sp#az-ad-sp-list) command to list the available service principals: - - ```azurecli - az ad sp list \ - --filter "startswith(displayName, '')" \ - --query "[].{objectId:id, displayName:displayName}" - ``` - - The `--filter` parameter accepts OData-style filters and can be used to filter the list as shown. The `--query` parameter limits the output to only the columns of interest. - -1. Use the [az ad group member add](/cli/azure/ad/group/member#az-ad-group-member-add) command to add members to the group: - - ```azurecli - az ad group member add \ - --group \ - --member-id - ``` - ---- - -## Assign roles to the group - -Next, determine what roles (permissions) your app needs on what resources and assign those roles to the Microsoft Entra group you created. Groups can be assigned a role at the resource, resource group, or subscription scope. This example shows how to assign roles at the resource group scope, since most apps group all their Azure resources into a single resource group. - -### [Azure portal](#tab/azure-portal) - -1. In the Azure portal, navigate to the **Overview** page of the resource group that contains your app. -1. Select **Access control (IAM)** from the left navigation. -1. On the **Access control (IAM)** page, select **+ Add** and then choose **Add role assignment** from the drop-down menu. The **Add role assignment** page provides several tabs to configure and assign roles. -1. On the **Role** tab, use the search box to locate the role you want to assign. Select the role, and then choose **Next**. -1. On the **Members** tab: - - For the **Assign access to** value, select **User, group, or service principal** . - - For the **Members** value, choose **+ Select members** to open the **Select members** flyout panel. - - Search for the Microsoft Entra group you created earlier and select it from the filtered results. Choose **Select** to select the group and close the flyout panel. - - Select **Review + assign** at the bottom of the **Members** tab. - - :::image type="content" source="../../media/app-role-assignment.png" alt-text="A screenshot showing how to assign a role to the Microsoft Entra group."::: - -1. On the **Review + assign** tab, select **Review + assign** at the bottom of the page. - -### [Azure CLI](#tab/azure-cli) - -1. Use the [az role definition list](/cli/azure/role/definition#az-role-definition-list) command to get the names of the roles that a service principal can be assigned to: - - ```azurecli - az role definition list \ - --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \ - --output table - ``` - -1. Use the [az role assignment create](/cli/azure/role/assignment#az-role-assignment-create) command to assign a role to an application service principal: - - ```azurecli - az role assignment create \ - --assignee "" \ - --role "" \ - --resource-group "" - ``` - - For information on assigning permissions at the resource or subscription level using the Azure CLI, see [Assign Azure roles using the Azure CLI](/azure/role-based-access-control/role-assignments-cli). - ---- - -## Set the app environment variables - -At runtime, certain credentials from the [Azure Identity library](/dotnet/api/azure.identity?view=azure-dotnet&preserve-view=true), such as `DefaultAzureCredential`, `EnvironmentCredential`, and `ClientSecretCredential`, search for service principal information by convention in the environment variables. There are multiple ways to configure environment variables when working with .NET, depending on your tooling and environment. - -Regardless of the approach you choose, configure the following environment variables for a service principal: - -- `AZURE_CLIENT_ID`: Used to identify the registered app in Azure. -- `AZURE_TENANT_ID`: The ID of the Microsoft Entra tenant. -- `AZURE_CLIENT_SECRET`: The secret credential that was generated for the app. - -### [Visual Studio](#tab/visual-studio) - -In Visual Studio, environment variables can be set in the `launchsettings.json` file in the `Properties` folder of your project. These values are pulled in automatically when the app starts. However, these configurations don't travel with your app during deployment, so you need to set up environment variables on your target hosting environment. - -```json -"profiles": { - "SampleProject": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "https://localhost:7177;http://localhost:5177", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "AZURE_CLIENT_ID": "", - "AZURE_TENANT_ID":"", - "AZURE_CLIENT_SECRET": "" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "AZURE_CLIENT_ID": "", - "AZURE_TENANT_ID":"", - "AZURE_CLIENT_SECRET": "" - } - } - } -``` - -### [Visual Studio Code](#tab/vs-code) - -In Visual Studio Code, environment variables can be set in the `launch.json` file of your project. These values are pulled in automatically when the app starts. However, these configurations don't travel with your app during deployment, so you need to set up environment variables on your target hosting environment. - -```json -"configurations": [ -{ - "env": { - "ASPNETCORE_ENVIRONMENT": "Development", - "AZURE_CLIENT_ID": "", - "AZURE_TENANT_ID":"", - "AZURE_CLIENT_SECRET": "" - } -} -``` - -### [Windows](#tab/windows) - -You can set environment variables for Windows from the command line. However, the values are accessible to all apps running on that operating system and could cause conflicts, so use caution with this approach. Environment variables can be set at the user or system level. - -```bash -# Set user environment variables -setx ASPNETCORE_ENVIRONMENT "Development" -setx AZURE_CLIENT_ID "" -setx AZURE_TENANT_ID "" -setx AZURE_CLIENT_SECRET "" - -# Set system environment variables - requires running as admin -setx ASPNETCORE_ENVIRONMENT "Development" /m -setx AZURE_CLIENT_ID "" /m -setx AZURE_TENANT_ID "" /m -setx AZURE_CLIENT_SECRET "" /m -``` - -PowerShell can also be used to set environment variables at the user or machine level: - -```powershell -# Set user environment variables -[Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development", "User") -[Environment]::SetEnvironmentVariable("AZURE_CLIENT_ID", "", "User") -[Environment]::SetEnvironmentVariable("AZURE_TENANT_ID", "", "User") -[Environment]::SetEnvironmentVariable("AZURE_CLIENT_SECRET", "", "User") - -# Set system environment variables - requires running as admin -[Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development", "Machine") -[Environment]::SetEnvironmentVariable("AZURE_CLIENT_ID", "", "Machine") -[Environment]::SetEnvironmentVariable("AZURE_TENANT_ID", "", "Machine") -[Environment]::SetEnvironmentVariable("AZURE_CLIENT_SECRET", "", "Machine") -``` - ---- +[!INCLUDE [auth-set-environment-variables](../includes/auth-set-environment-variables.md)] [!INCLUDE [Implement Service Principal](<../includes/implement-service-principal.md>)] diff --git a/docs/azure/sdk/authentication/on-premises-apps.md b/docs/azure/sdk/authentication/on-premises-apps.md index 02e22222b114f..7e1edad6d826f 100644 --- a/docs/azure/sdk/authentication/on-premises-apps.md +++ b/docs/azure/sdk/authentication/on-premises-apps.md @@ -3,170 +3,66 @@ title: Authenticate to Azure resources from .NET apps hosted on-premises description: This article describes how to authenticate your application to Azure services when using the Azure SDK for .NET in on-premises hosted apps. ms.topic: how-to ms.custom: devx-track-dotnet, engagement-fy23 -ms.date: 08/02/2024 +ms.date: 03/13/2025 --- # Authenticate to Azure resources from .NET apps hosted on-premises -Apps hosted outside of Azure (for example, on-premises or at a third-party data center) should use an application service principal to authenticate to Azure when accessing Azure resources. Application service principal objects are created using the app registration process in Azure. When an application service principal is created, a client ID and client secret will be generated for your app. The client ID, client secret, and your tenant ID are then stored in environment variables so they can be used by the Azure Identity library to authenticate your app to Azure at runtime. +Apps hosted outside of Azure, such as on-premises or in a third-party data center, should use an application service principal through [Microsoft Entra ID](/entra/fundamentals/whatis) to authenticate to Azure services. In the sections ahead, you learn: -A different app registration should be created for each environment the app is hosted in. This allows environment specific resource permissions to be configured for each service principal and make sure an app deployed to one environment doesn't talk to Azure resources that are part of another environment. - -## 1 - Register the application in Azure - -An app can be registered with Azure using either the Azure portal or the Azure CLI. - -### [Azure portal](#tab/azure-portal) - -Sign in to the [Azure portal](https://portal.azure.com/) and follow these steps. - -| Instructions | Screenshot | -|:----------------|-----------:| -| [!INCLUDE [Create app registration step 1](<../includes/on-premises-app-registration-azure-portal-1.md>)] | :::image type="content" source="../media/on-premises-app-registration-azure-portal-1-240px.png" lightbox="../media/on-premises-app-registration-azure-portal-1.png" alt-text="A screenshot showing how to use the top search bar in the Azure portal to find and navigate to the App registrations page." ::: | -| [!INCLUDE [Create app registration step 2](<../includes/on-premises-app-registration-azure-portal-2.md>)] | :::image type="content" source="../media/on-premises-app-registration-azure-portal-2-240px.png" lightbox="../media/on-premises-app-registration-azure-portal-2.png" alt-text="A screenshot showing the location of the New registration button in the App registrations page." ::: | -| [!INCLUDE [Create app registration step 3](<../includes/on-premises-app-registration-azure-portal-3.md>)] | :::image type="content" source="../media/on-premises-app-registration-azure-portal-3-240px.png" lightbox="../media/on-premises-app-registration-azure-portal-3.png" alt-text="A screenshot showing how to fill out the Register an application page by giving the app a name and specifying supported account types as accounts in this organizational directory only." ::: | -| [!INCLUDE [Create app registration step 4](<../includes/on-premises-app-registration-azure-portal-4.md>)] | :::image type="content" source="../media/on-premises-app-registration-azure-portal-4-240px.png" lightbox="../media/on-premises-app-registration-azure-portal-4.png" alt-text="A screenshot of the App registration page after the app registration has been completed. This screenshot shows the location of the application ID and tenant ID which will be needed in a future step. It also shows the location of the link to use to add an application secret for the app." ::: | -| [!INCLUDE [Create app registration step 5](<../includes/on-premises-app-registration-azure-portal-5.md>)] | :::image type="content" source="../media/on-premises-app-registration-azure-portal-5-240px.png" lightbox="../media/on-premises-app-registration-azure-portal-5.png" alt-text="A screenshot showing the location of the link to use to create a new client secret on the certificates and secrets page." ::: | -| [!INCLUDE [Create app registration step 6](<../includes/on-premises-app-registration-azure-portal-6.md>)] | :::image type="content" source="../media/on-premises-app-registration-azure-portal-6-240px.png" lightbox="../media/on-premises-app-registration-azure-portal-6.png" alt-text="A screenshot showing the page where a new client secret is added for the application service principal created by the app registration process." ::: | -| [!INCLUDE [Create app registration step 7](<../includes/on-premises-app-registration-azure-portal-7.md>)] | :::image type="content" source="../media/on-premises-app-registration-azure-portal-7-240px.png" lightbox="../media/on-premises-app-registration-azure-portal-7.png" alt-text="A screenshot showing the page with the generated client secret." ::: | - -### [Azure CLI](#tab/azure-cli) - -```azurecli -az ad sp create-for-rbac --name -``` +- How to register an application with Microsoft Entra to create a service principal +- How to assign roles to scope permissions +- How to authenticate using a service principal from your app code -The output of the command will be similar to the following. Make note of these values or keep this window open as you will need these values in the next step and will not be able to view the password (client secret) value again. +Using dedicated application service principals allows you to adhere to the principle of least privilege when accessing Azure resources. Permissions are limited to the specific requirements of the app during development, preventing accidental access to Azure resources intended for other apps or services. This approach also helps avoid issues when the app is moved to production by ensuring it isn't over-privileged in the development environment. -```json -{ - "appId": "00000000-1111-2222-3333-444444444444", - "displayName": "msdocs-dotnet-sdk-auth-prod", - "password": "abcdefghijklmnopqrstuvwxyz", - "tenant": "00000000-0000-0000-0000-000000000000" -} -``` +A different app registration should be created for each environment the app is hosted in. This allows environment specific resource permissions to be configured for each service principal and make sure an app deployed to one environment doesn't talk to Azure resources that are part of another environment. ---- +[!INCLUDE [auth-create-app-registration](../includes/auth-create-app-registration.md)] -## 2 - Assign roles to the application service principal +## Assign roles to the application service principal -Next, you need to determine what roles (permissions) your app needs on what resources and assign those roles to your app. Roles can be assigned a role at a resource, resource group, or subscription scope. This example shows how to assign roles for the service principal at the resource group scope, since most apps group all their Azure resources into a single resource group. +Next, determine what roles (permissions) your app needs on what resources and assign those roles to the service principal you created. Roles can be assigned at the resource, resource group, or subscription scope. This example shows how to assign roles at the resource group scope, since most apps group all their Azure resources into a single resource group. ### [Azure portal](#tab/azure-portal) -| Instructions | Screenshot | -|:----------------|-----------:| -| [!INCLUDE [Assign service principal to role step 1](<../includes/assign-service-principal-to-role-azure-portal-1.md>)] | :::image type="content" source="../media/assign-service-principal-to-role-azure-portal-1-240px.png" lightbox="../media/assign-service-principal-to-role-azure-portal-1.png" alt-text="A screenshot showing how to use the top search box in the Azure portal to locate and navigate to the resource group you want to assign roles (permissions) to." ::: | -| [!INCLUDE [Assign service principal to role step 2](<../includes/assign-service-principal-to-role-azure-portal-2.md>)] | :::image type="content" source="../media/assign-service-principal-to-role-azure-portal-2-240px.png" lightbox="../media/assign-service-principal-to-role-azure-portal-2.png" alt-text="A screenshot of the resource group page showing the location of the Access control (IAM) menu item." ::: | -| [!INCLUDE [Assign service principal to role step 3](<../includes/assign-service-principal-to-role-azure-portal-3.md>)] | :::image type="content" source="../media/assign-service-principal-to-role-azure-portal-3-240px.png" lightbox="../media/assign-service-principal-to-role-azure-portal-3.png" alt-text="A screenshot showing how to navigate to the role assignments tab and the location of the button used to add role assignments to a resource group." ::: | -| [!INCLUDE [Assign service principal to role step 4](<../includes/assign-service-principal-to-role-azure-portal-4.md>)] | :::image type="content" source="../media/assign-service-principal-to-role-azure-portal-4-240px.png" lightbox="../media/assign-service-principal-to-role-azure-portal-4.png" alt-text="A screenshot showing how to filter and select role assignments to be added to the resource group." ::: | -| [!INCLUDE [Assign service principal to role step 5](<../includes/assign-service-principal-to-role-azure-portal-5.md>)] | :::image type="content" source="../media/assign-service-principal-to-role-azure-portal-5-240px.png" lightbox="../media/assign-service-principal-to-role-azure-portal-5.png" alt-text="A screenshot showing the radio button to select to assign a role to a Microsoft Entra group and the link used to select the group to assign the role to." ::: | -| [!INCLUDE [Assign service principal to role step 6](<../includes/assign-service-principal-to-role-azure-portal-6.md>)] | :::image type="content" source="../media/assign-service-principal-to-role-azure-portal-6-240px.png" lightbox="../media/assign-service-principal-to-role-azure-portal-6.png" alt-text="A screenshot showing how to filter for and select the Microsoft Entra group for the application in the Select members dialog box." ::: | -| [!INCLUDE [Assign service principal to role step 7](<../includes/assign-service-principal-to-role-azure-portal-7.md>)] | :::image type="content" source="../media/assign-service-principal-to-role-azure-portal-7-240px.png" lightbox="../media/assign-service-principal-to-role-azure-portal-7.png" alt-text="A screenshot showing the completed Add role assignment page and the location of the Review + assign button used to complete the process." ::: | - -### [Azure CLI](#tab/azure-cli) - -A service principal is assigned a role in Azure using the [az role assignment create](/cli/azure/role/assignment#az-role-assignment-create) command: - -```azurecli -az role assignment create --assignee "{appId}" \ - --role "{roleName}" \ - --resource-group "{resourceGroupName}" -``` +1. In the Azure portal, navigate to the **Overview** page of the resource group that contains your app. +1. Select **Access control (IAM)** from the left navigation. +1. On the **Access control (IAM)** page, select **+ Add** and then choose **Add role assignment** from the drop-down menu. The **Add role assignment** page provides several tabs to configure and assign roles. +1. On the **Role** tab, use the search box to locate the role you want to assign. Select the role, and then choose **Next**. +1. On the **Members** tab: + - For the **Assign access to** value, select **User, group, or service principal** . + - For the **Members** value, choose **+ Select members** to open the **Select members** flyout panel. + - Search for the service principal you created earlier and select it from the filtered results. Choose **Select** to select the group and close the flyout panel. + - Select **Review + assign** at the bottom of the **Members** tab. -To get the role names to which a service principal can be assigned, use the [az role definition list](/cli/azure/role/definition#az-role-definition-list) command: + :::image type="content" source="../../media/app-role-assignment.png" alt-text="A screenshot showing how to assign a role to the service principal."::: -```azurecli -az role definition list \ - --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \ - --output table -``` +1. On the **Review + assign** tab, select **Review + assign** at the bottom of the page. -For example, to allow the service principal with the `appId` of `00000000-0000-0000-0000-000000000000` 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 "00000000-0000-0000-0000-000000000000" \ - --role "Storage Blob Data Contributor" \ - --resource-group "msdocs-dotnet-sdk-auth-example" -``` - -For information on assigning permissions at the resource or subscription level using the Azure CLI, see [Assign Azure roles using the Azure CLI](/azure/role-based-access-control/role-assignments-cli). - ---- - -## 3 - Configure environment variables for application - -The `DefaultAzureCredential` object will look for service principal credentials in a set of environment variables at runtime. There are multiple ways to configure environment variables when working with .NET depending on your tooling and environment. - -Regardless of which approach you choose, configure the following environment variables when working with a service principal: - -- `AZURE_CLIENT_ID` → The app ID value. -- `AZURE_TENANT_ID` → The tenant ID value. -- `AZURE_CLIENT_SECRET` → The password/credential generated for the app. - -### [IIS](#tab/iis-app-pool) - -If your app is hosted in IIS, it's recommended that you set environment variables per app pool to isolate settings between apps. - -```bash -appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='Contoso'].environmentVariables.[name='ASPNETCORE_ENVIRONMENT',value='Production']" /commit:apphost -appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='Contoso'].environmentVariables.[name='AZURE_CLIENT_ID',value='00000000-0000-0000-0000-000000000000']" /commit:apphost -appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='Contoso'].environmentVariables.[name='AZURE_TENANT_ID',value='11111111-1111-1111-1111-111111111111']" /commit:apphost -appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='Contoso'].environmentVariables.[name='AZURE_CLIENT_SECRET',value='=abcdefghijklmnopqrstuvwxyz']" /commit:apphost -``` - -You can also configure these settings directly using the `applicationPools` element inside of the `applicationHost.config` file: - -```xml - - - - - - - - - - -``` - -### [Windows](#tab/windows) - -You can set environment variables for Windows from the command line. However, when using this approach the values are accessible to all apps running on that operating system and may cause conflicts if you aren't careful. Environment variables can be set at either the user or system level. +### [Azure CLI](#tab/azure-cli) -```bash -# Set user environment variables -setx ASPNETCORE_ENVIRONMENT "Development" -setx AZURE_CLIENT_ID "00000000-0000-0000-0000-000000000000" -setx AZURE_TENANT_ID "11111111-1111-1111-1111-111111111111" -setx AZURE_CLIENT_SECRET "=abcdefghijklmnopqrstuvwxyz" +1. Use the [az role definition list](/cli/azure/role/definition#az-role-definition-list) command to get the names of the roles that a service principal can be assigned to: -# Set system environment variables - requires running as admin -setx ASPNETCORE_ENVIRONMENT "Development" -setx AZURE_CLIENT_ID "00000000-0000-0000-0000-000000000000" /m -setx AZURE_TENANT_ID "11111111-1111-1111-1111-111111111111" /m -setx AZURE_CLIENT_SECRET "=abcdefghijklmnopqrstuvwxyz" /m -``` + ```azurecli + az role definition list \ + --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \ + --output table + ``` -You can also use PowerShell to set environment variables at either the user or machine level: +1. Use the [az role assignment create](/cli/azure/role/assignment#az-role-assignment-create) command to assign a role to an application service principal: -```powershell -# Set user environment variables -[Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development", "User") -[Environment]::SetEnvironmentVariable("AZURE_CLIENT_ID", "00000000-0000-0000-0000-000000000000", "User") -[Environment]::SetEnvironmentVariable("AZURE_TENANT_ID", "11111111-1111-1111-1111-111111111111", "User") -[Environment]::SetEnvironmentVariable("AZURE_CLIENT_SECRET", "=abcdefghijklmnopqrstuvwxyz", "User") + ```azurecli + az role assignment create \ + --assignee "" \ + --role "" \ + --resource-group "" + ``` -# Set system environment variables - requires running as admin -[Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development", "Machine") -[Environment]::SetEnvironmentVariable("AZURE_CLIENT_ID", "00000000-0000-0000-0000-000000000000", "Machine") -[Environment]::SetEnvironmentVariable("AZURE_TENANT_ID", "11111111-1111-1111-1111-111111111111", "Machine") -[Environment]::SetEnvironmentVariable("AZURE_CLIENT_SECRET", "=abcdefghijklmnopqrstuvwxyz", "Machine") -``` + For information on assigning permissions at the resource or subscription level using the Azure CLI, see [Assign Azure roles using the Azure CLI](/azure/role-based-access-control/role-assignments-cli). --- -## 4 - Implement DefaultAzureCredential in your application +[!INCLUDE [auth-set-environment-variables](../includes/auth-set-environment-variables.md)] -[!INCLUDE [Implement DefaultAzureCredential](<../includes/implement-defaultazurecredential.md>)] +[!INCLUDE [implement-service-principal](../includes/implement-service-principal.md)] diff --git a/docs/azure/sdk/includes/auth-assign-group-roles.md b/docs/azure/sdk/includes/auth-assign-group-roles.md new file mode 100644 index 0000000000000..2a524c9cefa9d --- /dev/null +++ b/docs/azure/sdk/includes/auth-assign-group-roles.md @@ -0,0 +1,47 @@ +--- +ms.topic: include +ms.date: 03/13/2025 +--- + +## Assign roles to the group + +Next, determine what roles (permissions) your app needs on what resources and assign those roles to the Microsoft Entra group you created. Groups can be assigned a role at the resource, resource group, or subscription scope. This example shows how to assign roles at the resource group scope, since most apps group all their Azure resources into a single resource group. + +### [Azure portal](#tab/azure-portal) + +1. In the Azure portal, navigate to the **Overview** page of the resource group that contains your app. +1. Select **Access control (IAM)** from the left navigation. +1. On the **Access control (IAM)** page, select **+ Add** and then choose **Add role assignment** from the drop-down menu. The **Add role assignment** page provides several tabs to configure and assign roles. +1. On the **Role** tab, use the search box to locate the role you want to assign. Select the role, and then choose **Next**. +1. On the **Members** tab: + - For the **Assign access to** value, select **User, group, or service principal** . + - For the **Members** value, choose **+ Select members** to open the **Select members** flyout panel. + - Search for the Microsoft Entra group you created earlier and select it from the filtered results. Choose **Select** to select the group and close the flyout panel. + - Select **Review + assign** at the bottom of the **Members** tab. + + :::image type="content" source="../../media/group-role-assignment.png" alt-text="A screenshot showing how to assign a role to the Microsoft Entra group."::: + +1. On the **Review + assign** tab, select **Review + assign** at the bottom of the page. + +### [Azure CLI](#tab/azure-cli) + +1. Use the [az role definition list](/cli/azure/role/definition#az-role-definition-list) command to get the names of the roles that a Microsoft Entra group or service principal can be assigned to: + + ```azurecli + az role definition list \ + --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \ + --output table + ``` + +1. Use the [az role assignment create](/cli/azure/role/assignment#az-role-assignment-create) command to assign a role to the Microsoft Entra group you created: + + ```azurecli + az role assignment create \ + --assignee "" \ + --role "" \ + --resource-group "" + ``` + + For information on assigning permissions at the resource or subscription level using the Azure CLI, see [Assign Azure roles using the Azure CLI](/azure/role-based-access-control/role-assignments-cli). + +--- diff --git a/docs/azure/sdk/includes/auth-create-app-registration.md b/docs/azure/sdk/includes/auth-create-app-registration.md new file mode 100644 index 0000000000000..499df0dae5111 --- /dev/null +++ b/docs/azure/sdk/includes/auth-create-app-registration.md @@ -0,0 +1,59 @@ +--- +ms.topic: include +ms.date: 03/13/2025 +--- + +## Register the app in Azure + +Application service principal objects are created through an app registration in Azure using either the Azure portal or Azure CLI. + +### [Azure portal](#tab/azure-portal) + +1. In the Azure portal, use the search bar to navigate to the **App registrations** page. +1. On the **App registrations** page, select **+ New registration**. +1. On the **Register an application** page: + - For the **Name** field, enter a descriptive value that includes the app name and the target environment. + - For the **Supported account types**, select **Accounts in this organizational directory only (Microsoft Customer Led only - Single tenant)**, or whichever option best fits your requirements. +1. Select **Register** to register your app and create the service principal. + + :::image type="content" source="../../media/app-registration.png" alt-text="A screenshot showing how to create an app registration in the Azure portal."::: + +1. On the **App registration** page for your app, copy the **Application (client) ID** and **Directory (tenant) ID** and paste them in a temporary location for later use in your app code configurations. +1. Select **Add a certificate or secret** to set up credentials for your app. +1. On the **Certificates & secrets** page, select **+ New client secret**. +1. In the **Add a client secret** flyout panel that opens: + - For the **Description**, enter a value of Current. + - For the **Expires** value, leave the default recommended value of 180 days. + - Select **Add** to add the secret. +1. On the **Certificates & secrets** page, copy the **Value** property of the client secret for use in a future step. + + > [!NOTE] + > The client secret value is only displayed once after the app registration is created. You can add more client secrets without invalidating this client secret, but there's no way to display this value again. + +### [Azure CLI](#tab/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). + +1. Use the [az ad sp create-for-rbac](/cli/azure/ad/sp#az-ad-sp-create-for-rbac) command to create a new app registration and service principal for the app. + + ```azurecli + az ad sp create-for-rbac --name + ``` + + The output of this command resembles the following JSON: + + ```json + { + "appId": "00000000-0000-0000-0000-000000000000", + "displayName": "", + "password": "abcdefghijklmnopqrstuvwxyz", + "tenant": "11111111-1111-1111-1111-111111111111" + } + ``` + +1. Copy this output into a temporary file in a text editor, as you'll need these values in a future step. + + > [!NOTE] + > The client secret value is only displayed once after the app registration is created. You can add more client secrets without invalidating this client secret, but there's no way to display this value again. + +--- diff --git a/docs/azure/sdk/includes/auth-create-entra-group.md b/docs/azure/sdk/includes/auth-create-entra-group.md new file mode 100644 index 0000000000000..e838e01048ac6 --- /dev/null +++ b/docs/azure/sdk/includes/auth-create-entra-group.md @@ -0,0 +1,61 @@ +--- +ms.topic: include +ms.date: 03/11/2025 +--- + +## Create a Microsoft Entra group for local development + +Create a Microsoft Entra group to encapsulate the roles (permissions) the app needs in local development rather than assigning the roles to individual service principal objects. This approach offers the following advantages: + +- Every developer has the same roles assigned at the group level. +- If a new role is needed for the app, it only needs to be added to the group for the app. +- If a new developer joins the team, a new application service principal is created for the developer and added to the group, ensuring the developer has the right permissions to work on the app. + +### [Azure portal](#tab/azure-portal) + +1. Navigate to the **Microsoft Entra ID** overview page in the Azure portal. +1. Select **All groups** from the left-hand menu. +1. On the **Groups** page, select **New group**. +1. On the **New group** page, fill out the following form fields: + - **Group type**: Select **Security**. + - **Group name**: Enter a name for the group that includes a reference to the app or environment name. + - **Group description**: Enter a description that explains the purpose of the group. + + :::image type="content" source="../../media/create-group.png" alt-text="A screenshot showing how to create a group in the Azure portal."::: + +1. Select the **No members selected** link under **Members** to add members to the group. +1. In the flyout panel that opens, search for the service principal you created earlier and select it from the filtered results. Choose the **Select** button at the bottom of the panel to confirm your selection. +1. Select **Create** at the bottom of the **New group** page to create the group and return to the **All groups** page. If you don't see the new group listed, wait a moment and refresh the page. + +### [Azure CLI](#tab/azure-cli) + +1. Use the [az ad group create](/cli/azure/ad/group#az-ad-group-create) command to create groups in Microsoft Entra ID. + + ```azurecli + az ad group create \ + --display-name \ + --mail-nickname \ + --description + ``` + + The `--display-name` and `--mail-nickname` parameters are required. The name given to the group should be based on the name and environment of the app to indicate the group's purpose. + +1. To add members to the group, you need the object ID of the application service principal, which is different than the application ID. Use the [az ad sp list](/cli/azure/ad/sp#az-ad-sp-list) command to list the available service principals: + + ```azurecli + az ad sp list \ + --filter "startswith(displayName, '')" \ + --query "[].{objectId:id, displayName:displayName}" + ``` + + The `--filter` parameter accepts OData-style filters and can be used to filter the list as shown. The `--query` parameter limits the output to only the columns of interest. + +1. Use the [az ad group member add](/cli/azure/ad/group/member#az-ad-group-member-add) command to add members to the group: + + ```azurecli + az ad group member add \ + --group \ + --member-id + ``` + +--- diff --git a/docs/azure/sdk/includes/auth-set-environment-variables.md b/docs/azure/sdk/includes/auth-set-environment-variables.md new file mode 100644 index 0000000000000..7fece8908516e --- /dev/null +++ b/docs/azure/sdk/includes/auth-set-environment-variables.md @@ -0,0 +1,97 @@ +--- +ms.topic: include +ms.date: 03/11/2025 +--- + +## Set the app environment variables + +At runtime, certain credentials from the [Azure Identity library](/dotnet/api/azure.identity?view=azure-dotnet&preserve-view=true), such as `DefaultAzureCredential`, `EnvironmentCredential`, and `ClientSecretCredential`, search for service principal information by convention in the environment variables. There are multiple ways to configure environment variables when working with .NET, depending on your tooling and environment. + +Regardless of the approach you choose, configure the following environment variables for a service principal: + +- `AZURE_CLIENT_ID`: Used to identify the registered app in Azure. +- `AZURE_TENANT_ID`: The ID of the Microsoft Entra tenant. +- `AZURE_CLIENT_SECRET`: The secret credential that was generated for the app. + +### [Visual Studio](#tab/visual-studio) + +In Visual Studio, environment variables can be set in the `launchsettings.json` file in the `Properties` folder of your project. These values are pulled in automatically when the app starts. However, these configurations don't travel with your app during deployment, so you need to set up environment variables on your target hosting environment. + +```json +"profiles": { + "SampleProject": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7177;http://localhost:5177", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "AZURE_CLIENT_ID": "", + "AZURE_TENANT_ID":"", + "AZURE_CLIENT_SECRET": "" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "AZURE_CLIENT_ID": "", + "AZURE_TENANT_ID":"", + "AZURE_CLIENT_SECRET": "" + } + } + } +``` + +### [Visual Studio Code](#tab/vs-code) + +In Visual Studio Code, environment variables can be set in the `launch.json` file of your project. These values are pulled in automatically when the app starts. However, these configurations don't travel with your app during deployment, so you need to set up environment variables on your target hosting environment. + +```json +"configurations": [ +{ + "env": { + "ASPNETCORE_ENVIRONMENT": "Development", + "AZURE_CLIENT_ID": "", + "AZURE_TENANT_ID":"", + "AZURE_CLIENT_SECRET": "" + } +} +``` + +### [Windows](#tab/windows) + +You can set environment variables for Windows from the command line. However, the values are accessible to all apps running on that operating system and could cause conflicts, so use caution with this approach. Environment variables can be set at the user or system level. + +```bash +# Set user environment variables +setx ASPNETCORE_ENVIRONMENT "Development" +setx AZURE_CLIENT_ID "" +setx AZURE_TENANT_ID "" +setx AZURE_CLIENT_SECRET "" + +# Set system environment variables - requires running as admin +setx ASPNETCORE_ENVIRONMENT "Development" /m +setx AZURE_CLIENT_ID "" /m +setx AZURE_TENANT_ID "" /m +setx AZURE_CLIENT_SECRET "" /m +``` + +PowerShell can also be used to set environment variables at the user or system level: + +```powershell +# Set user environment variables +[Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development", "User") +[Environment]::SetEnvironmentVariable("AZURE_CLIENT_ID", "", "User") +[Environment]::SetEnvironmentVariable("AZURE_TENANT_ID", "", "User") +[Environment]::SetEnvironmentVariable("AZURE_CLIENT_SECRET", "", "User") + +# Set system environment variables - requires running as admin +[Environment]::SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development", "Machine") +[Environment]::SetEnvironmentVariable("AZURE_CLIENT_ID", "", "Machine") +[Environment]::SetEnvironmentVariable("AZURE_TENANT_ID", "", "Machine") +[Environment]::SetEnvironmentVariable("AZURE_CLIENT_SECRET", "", "Machine") +``` + +---