I'm hosting a WebApp on Azure (Linux) that connects to Cosmos DB.
When running the app locally, I use azd auth login, and it works perfectly. However, when the app is hosted on Azure, I understand that I should use a System Assigned Managed Identity for authentication.
Here's what I've done so far:
1. Enabled the System Assigned Managed Identity for the WebApp.
2. Assigned the Contributor and Reader roles to the resource group.
Despite these steps, the app throws a 500 error when trying to connect to Cosmos DB. Checking the browser dev tools confirmed the error but didn't provide much detail.
I also tried setting up the Cosmos DB dependency using the Visual Studio Publish GUI, but it made no difference.
What could I be missing? Are there additional permissions or configurations required for the managed identity to access Cosmos DB.
app throws a 500 error when trying to connect to Cosmos DB.
The error you're facing is due to the Contributor and Reader roles assigned to the resource group not being sufficient to access data from Azure Cosmos DB when using the System Assigned Managed Identity for authentication.
To read
data and executeQueries
in Cosmos DB, you need to assign the Cosmos DB Built-in Data Reader
or Cosmos DB Built-in Data Contributor
role to the web app.
These two roles cannot be assigned manually through the Azure Portal, so I used Azure Cloud Shell (PowerShell) to assign them. I ran below command to List roles and save the role Definition Id (name).
az cosmosdb sql role definition list --account-name <AzureCosmosDBaccountName> --resource-group <ResourceGroupName>
I added the following lines of code to the Program.cs
class.
builder.Services.AddSingleton<CosmosClient>(sp =>
{
var cosmosDbSettings = sp.GetRequiredService<IOptions<CosmosDbSettings>>().Value;
var credential = new DefaultAzureCredential();
return new CosmosClient(cosmosDbSettings.AccountEndpoint, credential);
});
Program.cs:
using BlazorApp6.Components;
using Microsoft.Azure.Cosmos;
using Microsoft.Extensions.Options;
using Azure.Identity;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.Configure<CosmosDbSettings>(builder.Configuration.GetSection("CosmosDb"));
builder.Services.AddSingleton<CosmosClient>(sp =>
{
var cosmosDbSettings = sp.GetRequiredService<IOptions<CosmosDbSettings>>().Value;
var credential = new DefaultAzureCredential();
return new CosmosClient(cosmosDbSettings.AccountEndpoint, credential);
});
builder.Services.AddSingleton<CosmosDbService<TodoItem>>(sp =>
{
var cosmosDbSettings = sp.GetRequiredService<IOptions<CosmosDbSettings>>().Value;
var cosmosClient = sp.GetRequiredService<CosmosClient>();
return new CosmosDbService<TodoItem>(cosmosClient, cosmosDbSettings.DatabaseName, cosmosDbSettings.ContainerName);
});
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();
I enabled the System Assigned Identity in the Azure Web App and make a note of its Object (Principal) ID.
By running the following command, I assigned the Cosmos DB Built-in Data Contributor
role to the Azure Web App, as it allows read, write, delete operations, and the ability to query and manage documents, items, or entities in containers.
az cosmosdb sql role assignment create --account-name <AzureCosmosDBaccountName> --resource-group <ResourceGroupName> -p "<object(principal)IDAzureWebApp>" --scope "/" --role-definition-id /00000000-0000-0000-0000-000000000002
Azure Output: