page_type | languages | products | description | urlFragment | |||||
---|---|---|---|---|---|---|---|---|---|
sample |
|
|
Connect to Azure SQL Database without using passwords |
azure-sql-db-passwordless-connections |
Building solutions that can take advtange of Azure SQL Database without the need to worry about passwords is a best practice. Your application we'll be more secure and you don't have to worry about changing and updating password to keep them secure.
To go passwordless you only need to follow this 5 steps:
Please note the is assumed that you already have an Azure SQL server and Azure SQL database ready to use for this sample. Full documentation on how to create both an Azure SQL server and an Azure SQL database is here: Quickstart: Create a single database - Azure SQL Database
Make sure that you have assigned an Azure Active Directory user as the Azure SQL server administrator: Configure and manage Azure AD authentication with Azure SQL
Using CLI, for example, if you want to associate your account as the Azure SQL administrator:
Get the user Object Id for your account (using AZ CLI and Ubuntu)
uid=`az ad user show --id <ad-account-email> --query "id" -o tsv`; echo $uid
the make the user the Azure SQL server admin:
az sql server ad-admin create -i $uid -u <ad-account-email> -g <resource-group> -s <azure-sql-server>.database.windows.net
This is how it will look like at the end of the process:
Create an App Service or an Azure Function (the same process will work also for a VM or a Container). You use the azure-deploy.sh
script to deploy the this sample application to Azure. The first time you run the script it will create an .env
file for you, that you have to fill out to specify the correct values for your environment:
ResourceGroup
: Name of the resource group that you want to use (a new one will be automatically created if the specified Resource Group does not existAppName
: Name of the App Service that will be createdLocation
: Where the sample will be deployedConnectionStrings__AzureSQL
: ADO.NET connection string to your Azure SQL Database
From the portal go to Settings->Identity in your App Service and enable the Managed Identity you prefer to use: System Assigned or User Assigned.
Important: A System Assigned Managed Identity will have the same name of the App Service (or the service you are using)
Again, the provided azure-deploy.sh
script will enable the System Assigned Managed Identity.
Now that your App Service has a Managed Identity, you need to allow that identity to access to the Azure SQL database you're using. Connect to the Azure SQL database with the tool you prefer, make sure you log in using an Azure AD account, and then execute the following commands:
create user [<app-service-name>] from external provider;
Replace <app-service-name
with the same value if you used for AppName
in the .env
file.
Perfect! You have just created a database user, connected with the Azure Active Directory account used by the App Service.
Now the database user need to have the correct permission to work on the database. To make it simple we can give it the permission of a local administrator, meaning that it will be able to do anything on the database.
alter role db_owner add member [<app-service-name>];
This may be ok for testing and this demo purposes, but is definitely too much for a production enviroment. Make sure to understand how permissions work in Azure SQL database, so that you can make sure only the minimum needed permissions are given to the App Service account:Permissions (Database Engine)
For example if you want to give permission to read and write from all tables in a database (but not modify their structure) you can use database roles, instead of making the database user part of the db_owner
role you can do the following:
alter role db_datareader add member [<app-service-name>];
alter role db_datawriter add member [<app-service-name>];
while if you want to limit access to a specific table and only for reading, here's an example:
grant select on [<table-name>] to [<app-service-name>]
Everything is set up now, so the only remaining work to do is to tell the application that it should connect to Azure SQL DB using the App Service Managed Identity.
Thanks to latest update to the Microsoft.Data.SqlClient library, you can now use the Managed Identity to connect to Azure SQL DB without the need to specify any password.
The easist way to have everything working is to use the Active Directory Default authentication
Here's a sample code:
// Use your own server, database
string ConnectionString = @"Server=demo.database.windows.net; Authentication=Active Directory Default; Encrypt=True; Database=testdb;";
using (var conn = new SqlConnection(connectionString))
{
await conn.OpenAsync();
// run sql command
conn.Close();
}
The Active Directory Default authentication works in this way:
- If you are running the sample locally, it will use the login you use to authenticate against Azure using Visual Studio, Visual Studio Code, Azure CLI or PowerShell
- If you have deployed and you are running the sample on Azure (using the provided
./azure-deploy.sh
script) it will use the defined App Service Managed Identity
Super easy and secure!
That's all. No more passwords! If you have deployed the sample on Azure, go to the App Service url (better if you can use a REST client tool such as Visual Studio, Insomnia, Curl or PowerShell's Invoke-RestMethod), for example:
https://test-who-am-i.azurewebsites.net/whoami
and you'll see with which account the App Service is logging in into Azure SQL database.
The code in WhoAmIController.cs
file contains two more endpoints:
/token
: That will use the Bearer token passed in the HTTP header to login in into Azure SQL DB. You can get the token for your account using AZ CLI:
az account get-access-token --resource "https://database.windows.net"
this is useful if you have a pass-through authentication use case (for example you're building an intranet website)
/impersonate
: Shows how you can impersonate another database user after logging in. This is useful, for example, if you have special security requirements, where some tables are locked down and only some specific dedicated user can access them.