Azure AD Managed Identity: Connecting Azure Web App and Slots with Azure SQL DB (without credentials)

jayendran

Jayendran Arumugam

Posted on June 17, 2020

Azure AD Managed Identity: Connecting Azure Web App and Slots with Azure SQL DB (without credentials)

Introduction

Managed Identity is a great way for connecting services in Azure without having to provide credentials like username, password or even clientid or client secrets. Please note that not all azure services support managed identity.  There are many great articles and blogs which discuss about in depth of managed identity and their types.You can see some of them in the See Also section.In this article we are going to see 2 main popular Azure resources to connect each other without providing any credentials in the code, they are azure app service (front-end) and azure sql database (back-end) by using System Managed Identity.

Using typical Connection String way

Usually we use the connection string to connect an azure sql database from any front-end. For instance lets say we are developing a dotnet application and want to connect to a back end (azure sql db) we will simply use the connection string like in the web.config below (which may be different for some other applications)

<connectionStrings>
<add name="DbConnection" connectionString="server=<sqlinstance>.database.windows.net;database=<dbname>;Uid=localadmin;Pwd={your_password_here};Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;" providerName="System.Data.SqlClient" />
</connectionStrings>
Enter fullscreen mode Exit fullscreen mode

From the C# code we will consume the connection string from the web.config to establish the connectivity from our code to backend like

using (var connection = new SqlConnection(connectionstring))
{
connection.Open();

//Executing some sql code

}
Enter fullscreen mode Exit fullscreen mode

Azure Key Vault for Connection String

It is always good to store this type of connection string in a secure place like
azure key vault secrets
. However we still need to store the client id and client secret  in a web.config if we aren't using the Managed Identity.See again storing a secret in a web.config, which is more like a chicken and egg problem  🐔🥚🐔

Here we need more sophisticated solution to solve this, which is the Managed Identity.

Using System Managed Identity way

Step 1: Enabling System Managed Identity in Web App

First we need to enable the System Managed Identity in our web app.


If you are using any slots you should also enable the same options in the slots as well 


Step 2: Creating Managed Identity User in Azure SQL

After we enabled the System Managed Identity in Azure App, we have to create a Managed Identity User in Azure sql db. To do so we must enable the Azure Active Directory Admin, then login to the database using the Active Directory account from either SSMS or Azure Data Studio.

We have to run the below query in the corresponding database.

CREATE USER [<App Service Name>] FROM EXTERNAL PROVIDER 

CREATE USER [<App Service Name>/slots/<slotname>] FROM EXTERNAL PROVIDER -- For apps in the slots

ALTER ROLE db_datareader ADD MEMBER [<App Service Name>] -- gives permission for normal app read to database
ALTER ROLE db_datawriter ADD MEMBER [<App Service Name>] -- gives permission for normal app write to database

ALTER ROLE db_datareader ADD MEMBER [<App Service Name>/slots/<slotname>] -- gives permission for slot app  read to database
ALTER ROLE db_datawriter ADD MEMBER [<App Service Name>/slots/<slotname>] -- gives permission for slot app  write to database
Enter fullscreen mode Exit fullscreen mode

By doing the above we are creating a user for our system managed identity of our app in the backend and providing required permissions like read/write a database.


Step 3: Remove the credentials from the Connection String

Finally we have to remove the credentials details like userid , password from the connection string ,like below

<connectionStrings>
<add name="DbConnection" connectionString="server=<sqlinstance>.database.windows.net;database=<dbname>;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;" providerName="System.Data.SqlClient" />
</connectionStrings>
Enter fullscreen mode Exit fullscreen mode

Step 4: 1-Line Magic Code

Now we just need to add a single line of code (magic) in our application before opening the connection like below

connection.AccessToken = await (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/");
Enter fullscreen mode Exit fullscreen mode

Sometime during the local testing if you have more than one subscription you will get error at the above line. To resolve that please use the optional parameters called tenant id for GetAccessTokenAsync method

connection.AccessToken = await (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/", <tenant-id>);
Enter fullscreen mode Exit fullscreen mode

In order to use the above code you also need to import a package called Microsoft.Azure.Services.AppAuthentication.
You can install it from nuget  like below

Install-Package Microsoft.Azure.Services.AppAuthentication -Version 1.5.0
Enter fullscreen mode Exit fullscreen mode

So finally our code will look like below

using (var connection = new SqlConnection(connectionstring))
{
connection.AccessToken = await (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/");
connection.Open();

//Executing some sql code

}
Enter fullscreen mode Exit fullscreen mode

Step 5: Testing it Locally

In order to test this from local machine we have to use
Azure CLI 2.0 or above
. So install the Az Cli then run the command 

az login
Enter fullscreen mode Exit fullscreen mode

It will prompt you for the credentials. Once you successfully logged in you will see your subscription details like in the below pic 

Now you can run your application in local.

(Note: If you have more than 1 tenant access you have to explicitly pass the tenantid in the GetAccessTokenAsync method)

After the successful run you can deploy the application in Azure.

Conclusion

Azure Managed Identity is going to remove the way of storing credentials in code even in azure key vault. In this article we saw only 2 services. But there are more and more services are coming along the way. Using this great feature we can do all the things inside Azure very safely and not leaking any credentials to others. 


See Also

💖 💪 🙅 🚩
jayendran
Jayendran Arumugam

Posted on June 17, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related