From 91d18ca8bd66f8a76a8c6587cc6d8ec921db8aa0 Mon Sep 17 00:00:00 2001 From: Alex Wolf Date: Tue, 11 Mar 2025 15:28:24 -0400 Subject: [PATCH 1/5] service-principal-on-prem --- docs/azure/media/group-role-assignment.png | Bin 0 -> 59257 bytes .../local-development-service-principal.md | 250 +----------------- .../sdk/authentication/on-premises-apps.md | 176 +++--------- .../sdk/includes/auth-assign-group-roles.md | 47 ++++ .../includes/auth-create-app-registration.md | 59 +++++ .../sdk/includes/auth-create-entra-group.md | 61 +++++ .../auth-set-environment-variables.md | 97 +++++++ 7 files changed, 306 insertions(+), 384 deletions(-) create mode 100644 docs/azure/media/group-role-assignment.png create mode 100644 docs/azure/sdk/includes/auth-assign-group-roles.md create mode 100644 docs/azure/sdk/includes/auth-create-app-registration.md create mode 100644 docs/azure/sdk/includes/auth-create-entra-group.md create mode 100644 docs/azure/sdk/includes/auth-set-environment-variables.md diff --git a/docs/azure/media/group-role-assignment.png b/docs/azure/media/group-role-assignment.png new file mode 100644 index 0000000000000000000000000000000000000000..b684b45960d833305a8108b0ad1156ab3658fa7c GIT binary patch literal 59257 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 [!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..6244f1b5a7b15 100644 --- a/docs/azure/sdk/authentication/on-premises-apps.md +++ b/docs/azure/sdk/authentication/on-premises-apps.md @@ -8,165 +8,63 @@ ms.date: 08/02/2024 # 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 to authenticate to Azure services. Application service principals 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. -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) +In the sections ahead, you learn: -```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 -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. 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) -| 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}" -``` - -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: +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. -```azurecli -az role definition list \ - --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \ - --output table -``` + :::image type="content" source="../../media/group-role-assignment.png" alt-text="A screenshot showing how to assign a role to the service principal."::: -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: +1. On the **Review + assign** tab, select **Review + assign** at the bottom of the page. -```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)] \ No newline at end of file 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..cb8f0ef1b9c77 --- /dev/null +++ b/docs/azure/sdk/includes/auth-assign-group-roles.md @@ -0,0 +1,47 @@ +--- +ms.topic: include +ms.date: 08/15/2024 +--- + +## 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). + +--- \ No newline at end of file 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..26cd76c95911e --- /dev/null +++ b/docs/azure/sdk/includes/auth-create-app-registration.md @@ -0,0 +1,59 @@ +--- +ms.topic: include +ms.date: 08/15/2024 +--- + +## 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. + +--- \ No newline at end of file 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..b1cfb16e23815 --- /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 + ``` + +--- \ No newline at end of file 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..e6c5daf93da3f --- /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 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") +``` + +--- From db84add6afc09ed72f04ce182eb13d119346fb04 Mon Sep 17 00:00:00 2001 From: Alex Wolf Date: Tue, 11 Mar 2025 15:55:35 -0400 Subject: [PATCH 2/5] fixes --- .../sdk/authentication/local-development-service-principal.md | 4 ++-- docs/azure/sdk/authentication/on-premises-apps.md | 2 +- docs/azure/sdk/includes/auth-assign-group-roles.md | 2 +- docs/azure/sdk/includes/auth-create-app-registration.md | 2 +- docs/azure/sdk/includes/auth-create-entra-group.md | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/azure/sdk/authentication/local-development-service-principal.md b/docs/azure/sdk/authentication/local-development-service-principal.md index 27c23d11a9ca4..7bf16926d7f43 100644 --- a/docs/azure/sdk/authentication/local-development-service-principal.md +++ b/docs/azure/sdk/authentication/local-development-service-principal.md @@ -26,9 +26,9 @@ 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. -[!INCLUDE [create-app-registration](../includes/create-app-registration.md)] +[!INCLUDE [create-app-registration](../includes/auth-create-app-registration.md)] -[!INCLUDE [create-entra-group](../includes/create-entra-group.md)] +[!INCLUDE [create-entra-group](../includes/auth-create-entra-group.md)] [!INCLUDE [auth-assign-group-roles](../includes/auth-assign-group-roles.md)] diff --git a/docs/azure/sdk/authentication/on-premises-apps.md b/docs/azure/sdk/authentication/on-premises-apps.md index 6244f1b5a7b15..ece434733ea2d 100644 --- a/docs/azure/sdk/authentication/on-premises-apps.md +++ b/docs/azure/sdk/authentication/on-premises-apps.md @@ -67,4 +67,4 @@ Next, determine what roles (permissions) your app needs on what resources and as [!INCLUDE [auth-set-environment-variables](../includes/auth-set-environment-variables.md)] -[!INCLUDE [implement-service-principal](../includes/implement-service-principal.md)] \ No newline at end of file +[!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 index cb8f0ef1b9c77..89c7b5fb6cf13 100644 --- a/docs/azure/sdk/includes/auth-assign-group-roles.md +++ b/docs/azure/sdk/includes/auth-assign-group-roles.md @@ -44,4 +44,4 @@ Next, determine what roles (permissions) your app needs on what resources and as 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). ---- \ No newline at end of file +--- diff --git a/docs/azure/sdk/includes/auth-create-app-registration.md b/docs/azure/sdk/includes/auth-create-app-registration.md index 26cd76c95911e..2f98500128a2c 100644 --- a/docs/azure/sdk/includes/auth-create-app-registration.md +++ b/docs/azure/sdk/includes/auth-create-app-registration.md @@ -56,4 +56,4 @@ Azure CLI commands can be run in the [Azure Cloud Shell](https://shell.azure.com > [!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. ---- \ No newline at end of file +--- diff --git a/docs/azure/sdk/includes/auth-create-entra-group.md b/docs/azure/sdk/includes/auth-create-entra-group.md index b1cfb16e23815..e838e01048ac6 100644 --- a/docs/azure/sdk/includes/auth-create-entra-group.md +++ b/docs/azure/sdk/includes/auth-create-entra-group.md @@ -58,4 +58,4 @@ Create a Microsoft Entra group to encapsulate the roles (permissions) the app ne --member-id ``` ---- \ No newline at end of file +--- From 72c861e5ad4163a28b0e6cb893521ca9860fb737 Mon Sep 17 00:00:00 2001 From: Alex Wolf Date: Tue, 11 Mar 2025 16:40:33 -0400 Subject: [PATCH 3/5] fixes --- docs/azure/sdk/authentication/on-premises-apps.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/azure/sdk/authentication/on-premises-apps.md b/docs/azure/sdk/authentication/on-premises-apps.md index ece434733ea2d..85c2164efe3fb 100644 --- a/docs/azure/sdk/authentication/on-premises-apps.md +++ b/docs/azure/sdk/authentication/on-premises-apps.md @@ -8,9 +8,7 @@ ms.date: 08/02/2024 # Authenticate to Azure resources from .NET apps hosted on-premises -Apps hosted outside of Azure, such as on-premises or in a third-party data center, should use an application service principal to authenticate to Azure services. Application service principals 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. - -In the sections ahead, you learn: +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: - How to register an application with Microsoft Entra to create a service principal - How to assign roles to scope permissions @@ -22,9 +20,9 @@ A different app registration should be created for each environment the app is h [!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, determine what roles (permissions) your app needs on what resources and assign those roles to the service principal 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. +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) @@ -38,7 +36,7 @@ Next, determine what roles (permissions) your app needs on what resources and as - 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. - :::image type="content" source="../../media/group-role-assignment.png" alt-text="A screenshot showing how to assign a role to the service principal."::: + :::image type="content" source="../../media/app-role-assignment.png" alt-text="A screenshot showing how to assign a role to the service principal."::: 1. On the **Review + assign** tab, select **Review + assign** at the bottom of the page. From 4f68fbb2a053b78c6751cfedd39963a1f2ac7def Mon Sep 17 00:00:00 2001 From: alexwolfmsft <93200798+alexwolfmsft@users.noreply.github.com> Date: Thu, 13 Mar 2025 11:27:57 -0400 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Scott Addie <10702007+scottaddie@users.noreply.github.com> --- docs/azure/sdk/includes/auth-assign-group-roles.md | 2 +- docs/azure/sdk/includes/auth-create-app-registration.md | 2 +- docs/azure/sdk/includes/auth-set-environment-variables.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/azure/sdk/includes/auth-assign-group-roles.md b/docs/azure/sdk/includes/auth-assign-group-roles.md index 89c7b5fb6cf13..2a524c9cefa9d 100644 --- a/docs/azure/sdk/includes/auth-assign-group-roles.md +++ b/docs/azure/sdk/includes/auth-assign-group-roles.md @@ -1,6 +1,6 @@ --- ms.topic: include -ms.date: 08/15/2024 +ms.date: 03/13/2025 --- ## Assign roles to the group diff --git a/docs/azure/sdk/includes/auth-create-app-registration.md b/docs/azure/sdk/includes/auth-create-app-registration.md index 2f98500128a2c..499df0dae5111 100644 --- a/docs/azure/sdk/includes/auth-create-app-registration.md +++ b/docs/azure/sdk/includes/auth-create-app-registration.md @@ -1,6 +1,6 @@ --- ms.topic: include -ms.date: 08/15/2024 +ms.date: 03/13/2025 --- ## Register the app in Azure diff --git a/docs/azure/sdk/includes/auth-set-environment-variables.md b/docs/azure/sdk/includes/auth-set-environment-variables.md index e6c5daf93da3f..7fece8908516e 100644 --- a/docs/azure/sdk/includes/auth-set-environment-variables.md +++ b/docs/azure/sdk/includes/auth-set-environment-variables.md @@ -78,7 +78,7 @@ 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 can also be used to set environment variables at the user or system level: ```powershell # Set user environment variables From 0395d79eeefac9d97b08d5ed0f72684118fa1c61 Mon Sep 17 00:00:00 2001 From: alexwolfmsft <93200798+alexwolfmsft@users.noreply.github.com> Date: Thu, 13 Mar 2025 13:10:05 -0400 Subject: [PATCH 5/5] Fix date --- docs/azure/sdk/authentication/on-premises-apps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/azure/sdk/authentication/on-premises-apps.md b/docs/azure/sdk/authentication/on-premises-apps.md index 85c2164efe3fb..7e1edad6d826f 100644 --- a/docs/azure/sdk/authentication/on-premises-apps.md +++ b/docs/azure/sdk/authentication/on-premises-apps.md @@ -3,7 +3,7 @@ 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