In one of the previous article, we have created a .NET Core web application and accessed the secrets stored in Azure key vault. We have seen how how to allow Visual studio to access the key vault.
In this article, let’s publish the web application as Azure app service. But then the app service will need managed identity to authenticate itself with the Azure key vault.
So, we will create the user-assigned managed identity and then assign it to Azure app service which will access the key vault.
Access the Web App
Create an Azure App Service instance and then publish the web app from the visual studio. Refer this article to know the detailed steps.
So, what you have is a .NET Core MVC Web application which is published as Azure app service.
If you try to access the Azure app service you published just now using URL https://app-service-name.azurewebsites.net
, then you will get an error below:
This is happening because we have registered the key vault provider while creating IHostBuilder
instance in Program.cs
.
This code tries to reach out to key vault and tries to get all the configurations from there. The key vault is not able to authenticate identity of the app service and the application crashes in startup resulting in above output.
System assigned vs User assigned
Let’s revise what’s the difference between these two types of managed identities.
System assigned managed identities are generated by system and generally they are tied to the resource for which they were created. The life-cycle of such identities is tied to the resource, meaning once you delete the resource, the associated system-assigned managed identity is also deleted.
e.g. in last blog post, we created system-assigned managed identity for Azure web app. We just had to enable a toggle on the App service in Azure portal. This identity would be deleted if we delete the app service instance.
User assigned managed identities, on the other hand, are created by administrators. Then, as the name suggests, it can be assigned to one or more Azure resources. Also, because it was not created for any specific resource, it is not automatically deleted by system when all the associated resources are deleted. It needs to be deleted by administrators.
In this article, we are going to see how to create user assigned managed identity and assign it to Azure App Service. This app service needs access to key vault to get storage account keys where it keeps the documents uploaded by web app’s users.
User assigned managed identity
Login to Azure portal and search for managed identities
in the search box provided in top navigation. A screen as in below snapshot would open.
Click on Add button to add the user assigned managed identity. On the new panel, below four inputs are required.
- Resource name, the name of user assigned managed identity
- Subscription, under which the resource should be created
- Resource group, the logical container to hold the managed identity
- Location, is the Azure region in which the identity would be created
After filling in the details, click on Create button to create the identity.
Assign to Azure App Service
In Azure Portal, open the resource group which has the Azure App Service which you created in the first step.
Open the Azure App Service instance and navigate to Settings -> Identity and then select User assigned tab. Click on Add button. It should open a new panel on right side.
Search for the identity which was created in previous step. Select it and then click on Add button on the panel.
That’s how easy it is. We just have assigned the user assigned managed identity to the Azure app service.
Access Policy at Key Vault
Now, again in Azure Portal, go to the key vaults and select the key vault which the Azure app service will connect to for reading the secrets.
Select Settings-> Access policies from the left navigation and then click on Add Access Policy link to add new access policy.
On the new panel, make sure to select two permissions – Get
and List
– for key permissions
, secret permissions
and certificate permissions
inputs.
Then click on Select principal which should open a new panel on right side. On this new panel, search for the name of the user-assigned managed identity which we have created for this demo above.
Select the user assigned managed identity and then click on Select button.
Then click on Add button to add the access policy. This will close add policy panel. Then click on Save button on Access policies
panel.
Publish the application to Azure and let’s try to access it.
The unexpected error…!
I did all configurations correctly, added identity, assigned it to web app and then added the access policy in key vault. The code was correct. So I was expecting everything to run as expected.
But, when I accessed the application, I was still getting “HTTP Error 500.30 - ANCM In-Process Start Failure
“. Then I went to Azure App Service’s Diagnose and solve problems option which shows Application Event Logs. I found below error there:
Unhandled exception. Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProviderException: Parameters: Connection String: [No connection string specified], Resource: https://vault.azure.net, Authority: https://login.windows.net/dddddddd-7777-8888-bbbb-999999999999. Exception Message: Tried the following 3 methods to get an access token, but none of them worked.
Resolution
After going through documentation, I found that a connection string needs to be specified while instantiating AzureServiceTokenProvider
. Below is the paragraph from the documentation:
Alternatively, you may authenticate with a user-assigned identity. For more information on user-assigned identities, see About Managed Identities for Azure resources. To authenticate with a user-assigned identity, you need to specify the Client ID of the user-assigned identity in the connection string. The connection string is specified in Connection String Support.
If we further take a look at the connection strings section, it states that the connection string needs to be used in below format if we want to use user assigned managed identity.
RunAs=App;AppId={ClientId of user-assigned identity}
For getting clientId
of the managed identity, go to managed identities screen again as specified above in creation section.
Then click on already created identity and it will open the details about it. On overview panel, you should be able to see the clientId
.
So I modified the CreateHostBuilder
method and specified the connection string as shown in below code snippet.
Please note that this code is not applicable if you want to run the application in Visual Studio.
If you want to work your code in both visual studio and app service with user assigned managed identity, then there should be a condition to identify where application is running. Based on that condition, the decision of whether to pass connection string parameter to AzureServiceTokenProvider
should be taken.
Now, republish the web app to Azure.
Run and Verify
Now if the app service is accessed again, it should show the upload file page as shown below. If file is uploaded, application will be able to read the storage account name, blob container and key from key vault and so the file will be uploaded to blob container.
Using Azure CLI
Below are the CLI commands that can be used for creating / deleting the user assigned managed identities.
Currently only some of the Azure services support managed identities, but they provide very convenient way to authenticate one resource while accessing another azure resource.
I hope this article has provided idea about how user assigned managed identities can be created and assigned to resources. Let me know your thoughts.
Thank you very much for a very helpful post.