Skip to content

Commit fc0e012

Browse files
committed
review changes
1 parent a32b374 commit fc0e012

File tree

1 file changed

+74
-107
lines changed

1 file changed

+74
-107
lines changed

articles/app-service/tutorial-connect-msi-sql-database.md

Lines changed: 74 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
---
2-
title: 'Tutorial: Access Azure web app data with managed identity'
2+
title: 'Tutorial: Use managed identity to connect an Azure web app to an Azure SQL database'
33
description: Learn how your app can use managed identity for secure access to Azure SQL Database and other Azure services without using passwords or secrets.
44
author: cephalin
55
ms.author: cephalin
66

77
ms.devlang: csharp
88
ms.topic: tutorial
9-
ms.date: 06/06/2025
9+
ms.date: 06/17/2025
1010
ms.custom: devx-track-csharp, mvc, cli-validate, devx-track-azurecli, devx-track-dotnet, AppServiceConnectivity
1111
---
12-
# Tutorial: Use a managed identity to connect to an Azure web app and Azure SQL back end
12+
# Tutorial: Use managed identity to connect an Azure web app to an Azure SQL database without secrets
1313

1414
[Azure App Service](overview.md) provides a highly scalable, self-patching web hosting service in Azure. App Service also provides a [managed identity](overview-managed-identity.md) for your app, which is a turnkey solution for securing access to [Azure SQL](/azure/azure-sql/) and other Azure services. Managed identities in App Service make your app more secure by eliminating secrets, such as credentials in connection strings.
1515

@@ -41,7 +41,7 @@ For guidance about using Azure Database for MySQL or Azure Database for PostgreS
4141
- .NET Framework 4.8 and above
4242
- .NET 6.0 and above
4343

44-
- Allow client connection from your computer to Azure, so you can debug your app in Visual Studio. You can add the client IP address by following the steps at [Manage server-level IP firewall rules using the Azure portal](/azure/azure-sql/database/firewall-configure#use-the-azure-portal-to-manage-server-level-ip-firewall-rules).
44+
- Allow client connection from your computer to Azure, so you can debug your app in your development environment. You can add the client IP address by following the steps at [Manage server-level IP firewall rules using the Azure portal](/azure/azure-sql/database/firewall-configure#use-the-azure-portal-to-manage-server-level-ip-firewall-rules).
4545

4646
- Sign in to Azure Cloud Shell or prepare your environment to use the Azure CLI.
4747
[!INCLUDE [azure-cli-prepare-your-environment-no-header.md](~/reusable-content/azure-cli/azure-cli-prepare-your-environment-no-header.md)]
@@ -87,7 +87,7 @@ Run the following commands in the Bash environment of Azure Cloud Shell, or afte
8787
az sql server ad-admin create --resource-group myResourceGroup --server-name <server-name> --display-name ADMIN --object-id <entra-id>
8888
```
8989

90-
## Use managed identity connectivity
90+
## Set up managed identity connectivity
9191

9292
The following steps configure your app to connect to Azure SQL Database with a system-assigned managed identity. To use a user-assigned identity, see [Tutorial: Connect to Azure databases from App Service without secrets using a managed identity](tutorial-connect-msi-azure-database.md).
9393

@@ -127,60 +127,33 @@ Grant the identity the minimum permissions your app needs.
127127

128128
The name of a system-assigned identity is always the same as the app name. The name of a system-assigned identity for a deployment slot is `<app-name>/slots/<slot-name>`. To grant permissions for a Microsoft Entra group, use the group's display name, such as `myAzureSQLDBAccessGroup`.
129129

130-
# [Azure CLI](#tab/azcli)
130+
1. In a PowerShell command line, sign in to SQL Database by using the following SQLCMD command, replacing `<server-name>` with your server name, `<db-name>` with your database name, and `<entra-user>` with the Microsoft Entra user name you used to set up the database. This Entra user has admin access to the database server by default.
131131

132-
<!--SQLCMD IS NO LONGER SUPPORTED IN BASH CLOUD SHELL as of April 2025. Use Powershell or portal.-->
133-
1. In your Bash terminal, sign in to SQL Database by using the following SQLCMD command, replacing `<server-name>` with your server name, `<db-name>` with your database name, and `<aad-user-name>` and `<aad-password>` with your Microsoft Entra user credentials.
134-
135-
```bash
136-
sqlcmd -S <server-name>.database.windows.net -d <db-name> -U <aad-user-name> -P <aad-password> -G -l 30
132+
```azurepowershell
133+
sqlcmd -S <servername>.database.windows.net -d <db-name> -U <entra-user> -G -l 30
137134
```
138135

139-
1. In the SQL prompt for the database you want, run the following commands to grant the minimum permissions your app needs, replacing `<identity-name>` with the name of the managed identity in Microsoft Entra ID.
136+
Follow the prompts to sign in.
137+
138+
1. At the SQL prompt, run the following commands to grant the minimum permissions your app needs, replacing `<identity-name>` with the name of the managed identity in Microsoft Entra ID.
140139

141140
```sql
142-
CREATE USER [<identity-name>] FROM EXTERNAL PROVIDER With OBJECT_ID='xxx';
141+
CREATE USER [<identity-name>] FROM EXTERNAL PROVIDER;
143142
ALTER ROLE db_datareader ADD MEMBER [<identity-name>];
144143
ALTER ROLE db_datawriter ADD MEMBER [<identity-name>];
145144
ALTER ROLE db_ddladmin ADD MEMBER [<identity-name>];
146145
GO
147146
```
148147

149-
1. Enter `EXIT` to return to the Bash prompt.
150-
151-
# [Azure portal](#tab/portal)
152-
153-
<!--These portal steps might or might not be correct.-->
154-
1. On your web app's page in the Azure portal, select **Identity** from the left navigation menu.
155-
156-
1. On the **System assigned** tab, make sure **Status** is set to **On**.
157-
158-
1. Under **Permissions**, select **Azure role assignments**.
159-
160-
1. On the **Azure role assignments** page, select **Add role assignment (Preview)**.
161-
162-
1. Use the **Add role assignment (Preview)** pane to add each of the following roles in turn.
163-
- **Scope**: Select **SQL**.
164-
- **Subscription**: Select your subscription.
165-
- **Resource**: Select your SQL server.
166-
- **Role**: Select each of the following roles:
167-
- **SQL DB Contributor**
168-
- **SQL Server Contributor**
169-
- **Reader**
170-
171-
After adding each role, select **Save**.
172-
173-
-----
174-
175148
> [!NOTE]
176149
> The backend managed identity services [maintain a token cache](overview-managed-identity.md#configure-target-resource) that updates the token for a target resource only when it expires. If you try to modify your SQL Database permissions after first getting a token with your app, you don't get a new token with updated permissions until the cached token expires.
177150
178-
### Modify the connection string
151+
### Remove the existing connection string
179152

180-
The same changes you made in *Web.config* or *appsettings.json* work with the managed identity. You can remove the existing connection string that Visual Studio created when it deployed your app the first time. To delete the connection string, run the following command, replacing `<app-name>` with the name of your app.
153+
The same changes you made in *Web.config* or *appsettings.json* work with the managed identity. You can remove the existing connection string you used when you deployed your app the first time. To delete the connection string, run the following command, replacing `<app-name>` with the name of your app.
181154

182155
```azurecli
183-
az webapp config connection-string delete --resource-group myResourceGroup --name <app-name> --setting-names MyDbConnection
156+
az webapp config connection-string delete --resource-group myResourceGroup --name <app-name> --setting-names <connection-string-name>
184157
```
185158

186159
## Set up your development environment
@@ -202,9 +175,9 @@ Visual Studio Code is integrated with Microsoft Entra authentication through the
202175
1. In the [Activity Bar](https://code.visualstudio.com/docs/getstarted/userinterface), select the **Azure** logo.
203176
1. In the **App Service** explorer, select **Sign in to Azure** and follow the instructions.
204177

205-
# [Azure CLI or Visual Studio macOS](#tab/macosclient)
178+
# [Azure CLI](#tab/macosclient)
206179

207-
Visual Studio for macOS isn't integrated with Microsoft Entra authentication. However, the Azure Identity client library can use tokens from Azure CLI.
180+
The Azure Identity client library can use tokens from Azure CLI.
208181

209182
1. To enable development and debugging in Visual Studio, [install Azure CLI](/cli/azure/install-azure-cli) on your local machine.
210183
1. Use your Microsoft Entra user to sign in to Azure with the command `az login --allow-no-subscriptions`.
@@ -218,52 +191,18 @@ The Azure Identity client library can use tokens from Azure PowerShell.
218191

219192
-----
220193

221-
## Modify your project
194+
## Modify your project and publish your app
222195

223-
You can now use Microsoft Entra authentication to develop and debug your Azure SQL database-backed web app. The steps differ depending on whether you have an ASP.NET or ASP.NET Core app.
196+
You can now use Microsoft Entra authentication to develop and debug your Azure SQL database-backed web app.
224197

225-
- An ASP.NET app uses [Entity Framework](/ef/ef6/) by default.
226-
- An ASP.NET Core app uses [Entity Framework Core](/ef/core/) by default.
198+
The app uses a database context to connect with the database. You update the code to refer to the Entity Framework SQL Server provider, which depends on the modern [Microsoft.Data.SqlClient](https://github.com/dotnet/SqlClient) ADO.NET provider. The Entity Framework provider replaces the built-in `System.Data.SqlClient` SQL Server provider, and includes support for Microsoft Entra ID authentication methods. For more information, see [Microsoft.EntityFramework.SqlServer}](https://www.nuget.org/packages/Microsoft.EntityFramework.SqlServer).
227199

228-
# [ASP.NET app](#tab/ef)
200+
`[DbConfigurationType(typeof(MicrosoftSqlDbConfiguration))]` works locally to use `Microsoft.Data.SqlClient` for the database context, but because `System.Data.SqlClient` is hardcoded as the provider in Azure App Service, you need to extend `MicrosoftSqlDbConfiguration` to redirect references to `System.Data.SqlClient` to `Microsoft.Data.SqlClient` instead.
229201

230-
1. With your app project open in Visual Studio, go to the **Package Manager Console**, add the NuGet package [Azure.Identity](https://www.nuget.org/packages/Azure.Identity), and update `Entity Framework`.
202+
The steps differ depending on whether you have an ASP.NET or ASP.NET Core app.
231203

232-
```powershell
233-
Install-Package Azure.Identity
234-
Update-Package EntityFramework
235-
```
236-
> [!NOTE]
237-
> The token caching feature for Managed Identity is available starting from `Azure.Identity` version 1.8.0. To help reduce network port usage, consider updating `Azure.Identity` to this version or later.
238-
239-
1. Open *Models/MyDbContext.cs*, and in the `DbContext` object, add the following code to the default constructor.
240-
241-
```csharp
242-
Azure.Identity.DefaultAzureCredential credential;
243-
var managedIdentityClientId = ConfigurationManager.AppSettings["ManagedIdentityClientId"];
244-
if(managedIdentityClientId != null ) {
245-
//User-assigned managed identity Client ID is passed in via ManagedIdentityClientId
246-
var defaultCredentialOptions = new DefaultAzureCredentialOptions { ManagedIdentityClientId = managedIdentityClientId };
247-
credential = new Azure.Identity.DefaultAzureCredential(defaultCredentialOptions);
248-
}
249-
else {
250-
//System-assigned managed identity or logged-in identity of Visual Studio, Visual Studio Code, Azure CLI or Azure PowerShell
251-
credential = new Azure.Identity.DefaultAzureCredential();
252-
}
253-
var conn = (System.Data.SqlClient.SqlConnection)Database.Connection;
254-
var token = credential.GetToken(new Azure.Core.TokenRequestContext(new[] { "https://database.windows.net/.default" }));
255-
conn.AccessToken = token.Token;
256-
```
257-
258-
The preceding code uses [Azure.Identity.DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential) to get a usable token for SQL Database from Microsoft Entra ID, and then adds it to the database connection. You can customize `DefaultAzureCredential`, but it's already versatile. When `DefaultAzureCredential` runs in App Service, it uses the app's system-assigned managed identity by default.
259-
260-
If you prefer to use a user-assigned managed identity, add a new app setting named `ManagedIdentityClientId` and enter the `Client Id` GUID from your user-assigned managed identity in the `value` field. When the code runs locally, it can get a token using the signed-in identity of Visual Studio, Visual Studio Code, Azure CLI, or Azure PowerShell.
261-
262-
1. Open *Web.config*, find the connection string called `MyDbConnection`, and replace its `connectionString` value with `"server=tcp:<server-name>.database.windows.net;database=<db-name>"`, replacing `<server-name` and `<db-name>` with your server name and database name. This connection string is used by the default constructor in *Models/MyDbContext.cs*.
263-
264-
You now have everything you need to connect to SQL Database when you debug in Visual Studio. Your code uses the Microsoft Entra user you configured when you set up your dev environment. Later, you can set up SQL Database to allow connection from the managed identity of your App Service app.
265-
266-
1. Press **Ctrl**+**F5** to run the app. The CRUD app in your browser now connects to the Azure SQL database directly, using Microsoft Entra authentication. This setup lets you run database migrations from Visual Studio.
204+
- An ASP.NET Core app uses [Entity Framework Core](/ef/core/) by default.
205+
- An ASP.NET app uses [Entity Framework](/ef/ef6/) by default.
267206

268207
# [ASP.NET Core app](#tab/efcore)
269208

@@ -273,35 +212,72 @@ You can now use Microsoft Entra authentication to develop and debug your Azure S
273212
Install-Package Microsoft.Data.SqlClient
274213
```
275214

276-
1. In [Tutorial: Build an ASP.NET Core and SQL Database app in Azure App Service](tutorial-dotnetcore-sqldb-app.md), the `MyDbConnection` connection string in *appsettings.json* isn't used at all yet. The local and Azure environments both get connection strings from their respective environment variables, to keep connection secrets out of the source file. But Microsoft Entra authentication doesn't use secrets.
277-
278-
In *appsettings.json*, replace the value of the `MyDbConnection` connection string with the following code, replacing `<server-name` and `<database-name>` with your server name and database name.
215+
1. In *appsettings.json*, replace the value of the connection string with the following code, replacing `<server-name` and `<database-name>` with your server name and database name.
279216

280217
```json
281218
"Server=tcp:<server-name>.database.windows.net;Authentication=Active Directory Default; Database=<database-name>;"
282219
```
283220

284221
> [!NOTE]
285-
> You can use [Active Directory Default](/sql/connect/ado-net/sql/azure-active-directory-authentication#using-active-directory-default-authentication) authentication both on your local machine and in Azure App Service. The driver can acquire a token from Microsoft Entra ID in several different ways.
222+
> You can use [Microsoft Entra Default](/sql/connect/ado-net/sql/azure-active-directory-authentication#using-active-directory-default-authentication) authentication both on your local machine and in Azure App Service. The driver can acquire a token from Microsoft Entra ID in several different ways.
223+
>
224+
>If the app is deployed, the driver gets a token from the app's system-assigned managed identity. The driver can also authenticate with a user-assigned managed identity if you include `User Id=<client-id-of-user-assigned-managed-identity>;` in your connection string.
286225
>
287-
>If the app is deployed, the driver gets a token from the app's system-assigned managed identity. The driver can also authenticate with a user-assigned managed identity if you include `User Id=<client-id-of-user-assigned-managed-identity>;` in your connection string. If the app is running locally, it tries to get a token from Visual Studio, Visual Studio Code, or Azure CLI.
226+
>The `DefaultAzureCredential` class caches the token in memory and retrieves it from Microsoft Entra ID just before expiration. You don't need any custom code to refresh the token.
288227
289228
You now have everything you need to connect to SQL Database when you debug in Visual Studio. Your code uses the Microsoft Entra user you configured when you set up your dev environment. You can set up SQL Database later to allow connection from the managed identity of your App Service app.
290229

291-
The `DefaultAzureCredential` class caches the token in memory and retrieves it from Microsoft Entra ID just before expiration. You don't need any custom code to refresh the token.
230+
1. Run your app. The CRUD app in your browser connects to the Azure SQL database directly, using Microsoft Entra authentication. This setup lets you run database migrations from Visual Studio.
292231

293-
1. When you run your app, the CRUD app in your browser now connects to the Azure SQL database directly, using Microsoft Entra authentication. This setup lets you run database migrations from Visual Studio.
232+
1. Publish your changes using the following Git commands:
294233

295-
---
234+
```bash
235+
git commit -am "configure managed identity"
236+
git push azure main
237+
```
296238

239+
# [ASP.NET app](#tab/ef)
297240

298-
## Publish your changes
241+
1. From the Visual Studio **Tools** menu, select **NuGet Package Manager** > **Package Manager Console**.
299242

300-
Now, publish your changes to Azure. The steps differ depending on whether you have an ASP.NET or ASP.NET Core app.
243+
1. In the **Package Manager Console**, install the following packages:
301244

302-
# [ASP.NET app](#tab/ef)
245+
```powershell
246+
Install-Package Microsoft.Data.SqlClient
247+
Install-Package Microsoft.EntityFramework.SqlServer
248+
```
249+
250+
1. In *Models/MyDatabaseContext.cs* or other file that configures the database context, add the following class:
251+
252+
```csharp
253+
public class AppServiceConfiguration : MicrosoftSqlDbConfiguration
254+
{
255+
public AppServiceConfiguration()
256+
{
257+
SetProviderFactory("System.Data.SqlClient", Microsoft.Data.SqlClient.SqlClientFactory.Instance);
258+
SetProviderServices("System.Data.SqlClient", MicrosoftSqlProviderServices.Instance);
259+
SetExecutionStrategy("System.Data.SqlClient", () => new MicrosoftSqlAzureExecutionStrategy());
260+
}
261+
}
262+
```
303263

304-
Publish your changes from Visual Studio.
264+
1. Add the following attribute to *MyDatabaseContext.cs*:
265+
266+
```csharp
267+
[DbConfigurationType(typeof(AppServiceConfiguration))]
268+
```
269+
270+
1. Open *web.config*, find the connection string called `MyDbConnection`, and replace its `connectionString` value with
271+
272+
`"server=tcp:<server-name>.database.windows.net;Authentication=Active Directory Default; Database=<db-name>;"`
273+
274+
replacing `<server-name` and `<db-name>` with your server name and database name. This connection string is used by the default constructor in *Models/MyDatabaseContext.cs*.
275+
276+
1. In *web.config*, remove the `entityFramework/providers/provider` section and line: `<provider invariantName="System.Data.SqlClient" .../>`.
277+
278+
You now have everything you need to connect to SQL Database when you debug in Visual Studio. Your code uses the Microsoft Entra user you configured when you set up your dev environment.
279+
280+
1. In Visual Studio, press **Ctrl**+**F5** to run the app. The CRUD app in your browser now connects to the Azure SQL database directly, using Microsoft Entra authentication. This setup lets you run database migrations from Visual Studio.
305281

306282
1. In **Solution Explorer**, right-click your **DotNetAppSqlDb** project and select **Publish**.
307283

@@ -312,18 +288,9 @@ Publish your changes from Visual Studio.
312288
> [!IMPORTANT]
313289
> Ensure that your app service name doesn't duplicate any existing [app registrations](/azure/active-directory/manage-apps/add-application-portal), which leads to Principal ID conflicts.
314290
315-
# [ASP.NET Core app](#tab/efcore)
316-
317-
Publish your changes using the following Git commands:
318-
319-
```bash
320-
git commit -am "configure managed identity"
321-
git push azure main
322-
```
323-
324291
---
325292

326-
### View and test the app
293+
### Test the app
327294

328295
When the new webpage shows your to-do list, your app is connecting to the database using the managed identity.
329296

0 commit comments

Comments
 (0)