La sécurisation des services est une problématique importante lorsqu’on utilise des composants sur le Cloud.

Il est naturel de se poser les bonnes questions pour garder une maîtrise sur son système d’information. La plateforme Azure de Microsoft a alors introduit plusieurs options : la connexion aux bases SQL via une authentification Azure AD, ainsi que les Managed Identity sur les AppServices. Voyons comment combiner ces deux notions afin de réaliser une connexion sans mot de passe.

Lorsque vous créez un AppService, il est désormais possible de spécifier une Managed Identity, en System-Assigned. Cette notion est très intéressante, car il s’agit de fournir à l’AppService une identité totalement gérée par Azure. En System-Assigned, cette identité aura exactement le même cycle de vie que l’application web : elle se créera au même moment, et sera supprimée si l’AppService disparaît. Afin de configurer un AppService en Managed Identity, il est possible de passer par le portail Azure dans la section correspondante.

 

 

La configuration est également présente dans le modèle de déploiement par script ARM. Cette option est plus intéressante si vous souhaitez industrialiser votre déploiement, ce qui est une bonne pratique lorsqu’on travaille sur le Cloud. Les lignes suivantes sont à ajouter :

{
  "apiVersion": "2015-08-01",
  "type": "Microsoft.Web/sites",
  "name": "[variables('siteName')]",
  "location": "[resourceGroup().location]",
  "identity": {
    "type": "SystemAssigned"
  },
  //... Remaining code removed
}

D’autre part, en rajoutant les paramètres suivants en variables de sortie, vous avez la possibilité de récupérer l’ID de l’annuaire Azure AD et l’ID du compte de service qui a été généré en tant qu’identité gérée pour l’AppService.

{
  "outputs": {
    "tenantId": {
      "type": "string",
      "value": "[reference(concat(resourceId('Microsoft.Web/sites', variables('siteName')), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').tenantId]"
    },
    "principalId": {
      "type": "string",
      "value": "[reference(concat(resourceId('Microsoft.Web/sites', variables('siteName')), '/providers/Microsoft.ManagedIdentity/Identities/default'), '2015-08-31-PREVIEW').principalId]"
    }
  }
}

La sortie que vous obtiendrez sera alors de la forme suivante :

{
  "tenantId": "_azure_ad_tenantId_",
  "principalId": "_azure_ad_principalId_"
}

Pour configurer la base de données avec une authentification Azure AD, vous pouvez définir le compte à utiliser via le portail Azure. Il faut passer cette fois sur le serveur Azure SQL correspondant, dans la section Active Directory Admin. Vous remarquerez que via le portail, seuls les utilisateurs ou les groupes peuvent être sélectionnés.

 

En script ARM, l’ajout passe par les lignes suivantes sur la ressource correspondante :

{
  "type": "administrators",
  "name": "activeDirectory",
  "apiVersion": "2014-04-01-preview",
  "location": "[resourceGroup().location]",
  "properties": {
    "administratorType": "ActiveDirectory",
    "login": "_azure_ad_login_",
    "sid": "_azure_ad_sid_",
    "tenantId": "_azure_ad_tenantId_"
  }
}

Dans notre cas, nous allons passer par un groupe Azure AD. Cette solution a le mérite de définir un objet AD moins « volatile » que l’identité managée par Azure pour l’AppService, qui a son propre cycle de vie.

Après ajout du groupe « DB Admins » en tant qu’administrateur, nous pouvons utiliser PowerShell pour rajouter l’identité de l’AppService dans ce groupe. Néanmoins, nous allons plutôt créer un autre groupe, « DB Readers » que nous n’allons pas définir en tant qu’administrateur de la base de données. En rajoutant le MSI dans ce groupe, nous aurons ainsi une gestion plus fine de ses droits.

Connect-AzureAD -TenantId "_azure_ad_tenantId_" 
Add-AzureADGroupMember -ObjectId "_azure_ad_groupId_" -RefObjectId "_managed_identity_principalId_" 

 

Enfin, côté SQL, pour utiliser le groupe DB Readers, vous pouvez exploiter la commande suivante :

CREATE USER [DB Readers] FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER [DB Readers]; 

 

Pour terminer, dans le code de votre application web, vous pouvez utiliser le package Nuget “Microsoft.Azure.Services.AppAuthentication”, et les commandes suivantes pour vous connecter à la base de données avec l’authentification Azure AD.

 
using (SqlConnection connection = new SqlConnection(this.connectionString))
{
	connection.AccessToken = (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/").Result; 
	//... Remaining code removed 
}

Le format de la chaîne de connexion est le suivant :

"Data Source=_azure_sql_server_.database.windows.net;Initial Catalog=_database_name_;"

 

Si votre compte d’utilisateur peut accéder à la base de données (notamment si vous vous êtes ajouté dans un des groupes), vous pouvez tester votre application localement sous Visual Studio (version 15.6+). En effet, lors de la récupération d’un jeton d’authentification, c’est le compte avec lequel vous vous êtes connecté qui sera utilisé.

 

 

Vous pouvez également utiliser SQL Management Studio, avec l’option « Authentification par mot de passe ».

 

De cette façon, vous avez votre application web qui se connecte à l’Azure AD, avec une authentification managée par Azure et sans mot de passe ! D’autre part, vous pouvez à tout moment gérer les droits SQL de cette identité en utilisant l’administration standard des utilisateurs SQL.

livre blanc From Zero to Hero 2 réseau azure