Azure

Azure Managed Service Identities (MSI)

Nov 4, 2019

Nicolas Bailly

Nous allons voir dans cet article ce que nous propose Azure pour faciliter la sécurisation des ressources sans pour autant négliger la sécurité. Lorsque des identifiants sont stockés dans des fichiers de configuration, il y a toujours un risque que quelqu’un les récupère et effectue de mauvaises manipulations consciemment ou non. Même si avec Key Vault, on limite ce risque, le mieux étant encore qu’il n’y ait plus d’identifiants. Pour cela, Azure permet de donner des permissions à des ressources grâce à Managed Service Identity (MSI). Aucun identifiant à stocker, tout se passe au sein de Azure.

Nous allons voir plus précisément comment procéder avec 2 exemples : un app Service qui accède à Key Vault et un app service qui accède à une base de données.

Activation de MSI sur une App Service

Nous allons tout d’abord activer MSI, ce qui n’est pas fait par défaut. Pour mettre en place MSI sur un app service, allez sur votre App Service et sélectionnez « Managed service identity ». Par défaut c’est sur « Off ». Sélectionnez « On » et sauvegardez

Vous pouvez également le faire en powershell avec la commande suivante :

Set-AzureRmWebApp -AssignIdentity $true -Name $webAppName -ResourceGroupName $myResourceGroup 

Ainsi, l’application est enregistrée dans Azure AD de la même manière que ce que vous pouvez faire manuellement avec les « App registered ».

Accès à Azure Key Vault depuis une App Service

Azure key Vault permet de stocker des données sensibles afin qu’une application n’ait pas à les stocker dans ses fichiers de configurations. Mais pour accéder à un Key Vault, il faut des identifiants, qui seront stockés dans … un fichier de configuration. Un comble. Associer MSI à Azure Key Vault permet de ne plus avoir aucune donnée sensible dans les fichiers de configuration et ainsi d’optimiser la sécurité. Pour donner accès à votre Key Vault, allez dans le menu Access Policies de votre ressource. Grâce à MSI, ici vous pouvez retrouver votre App Service sur laquelle vous pouvez donner des permissions.

Key Vault permettant de stocker des clés, des mots de passe ou des certificats, il faut donner les droits qui vont bien à votre application. Dans cet exemple, nous faisons le choix de ne donner accès qu’en lecture à notre application :

Nous pouvons voir que les droits ont bien été donné à l’app service :

Pour faire la même chose en PowerShell, nous récupérons dans un premier temps le « service principal » puis nous donnons les accès à celui-ci :

$serviceprincipal = Get-AzureRmADServicePrincipal -SearchString $webAppName
Set-AzureRmKeyVaultAccessPolicy -VaultName $keyVaultName -objectId $serviceprincipal.Id -PermissionsToSecrets get -PermissionsToKeys get -PermissionsToCertificates get -PassThru

Nous sommes sur un environnement de développement, c’est pourquoi, nous admettrons qu’en tant que développeur, j’ai également les droits sur le Key Vault. Mais l’intérêt est qu’en environnement de production, seules les personnes nécessaires à l’administration de ce Key Vault auront les droits.

Exemple de code : Imaginons qu’une application doive accéder à une base de données nécessitant un mot de passe. Nous stockons ce mot de passe dans le Key Vault:

Nous allons écrire une méthode, qui récupère ce mot de passe. Pour cela, il faut d’abord installer les packages nuget suivants :

  • Microsoft.Azure.Services.AppAuthentication
  • Microsoft.Azure.KeyVault

Et voici le code C# qui permet de récupérer le mot de passe :

private async Task<string> GetDbPassword(string vaultUrl)
{
    var tokenProvider = new AzureServiceTokenProvider();
    var keyVault = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback));
    var secret = await keyVault.GetSecretAsync(vaultUrl, "DbPassword");
    return secret.Value;
}

Les seuls paramètres nécessaires sont l’URL du Key Vault (disponible dans les propriétés de celui-ci) et le nom de la clé à récupérer. Aucun identifiant n’est précisé pour accéder au Key Vault.

Si vous exécutez ce code sur votre machine, vous aurez très probablement l’erreur suivante : KeyVaultErrorException: Operation returned an invalid status code ‘Unauthorized’

L’accès est refusé alors que nous avons vu que j’ai bien les droits sur le Key Vault. Le problème vient du fait que l’on n’est pas authentifié et donc aucune permission n’est accordée. Pour que cela fonctionne localement, il faut d’abord lancer cette commande Azure CLI :

az login
az account set --subscription "<My Subscription Name>"

« az login » va ouvrir un navigateur pour vous authentifier et la commande suivante vous positionne sur la souscription sur laquelle le Key Vault a été créé. Si vous n’avez accès qu’à une seule souscription, cette seconde commande est facultative.

Exemple d’un App Service qui accède à une base de données Sql Server

Sur un environnement on-premise, lorsqu’un site hébergé dans IIS doit accéder à une base de données Sql Server, on donne les droits au compte de service de l’application pool sur la base de données. Ainsi, aucun identifiant n’est indiqué dans la chaine de connexion.

Sur un App Service, il n’y a pas d’application pool ni de compte de service. Nous allons voir comment faire de même avec MSI sur une application complètement hébergée sur Azure en mode PaaS (site + base de données).

Nous reprenons, l’App service de l’exemple précédent à laquelle nous allons connecter une base de données. Nous considérons donc que MSI est activée sur cette App Service.

Tout d’abord, les opérations qui vont suivre donne des droits d’accès sur la base de données, il faut être administrateur du serveur SQL pour les réaliser. Sur le portail Azure, sélectionnez le serveur SQL concerné. Puis définissez-vous comme admin :

Pour le faire en PowerShell :

Set-AzureRmSqlServerActiveDirectoryAdministrator -ResourceGroupName $resourceGroupName -ServerName $sqlServerName -DisplayName $adminUser

Pour donner accès à la base de données depuis l’application web, il faut ajouter l’application dans un groupe Azure AD puis donner les permissions à ce groupe dans la base de données. Le script PowerShell  qui suit, récupère l’identifiant de l’application et l’ajoute dans un nouveau groupe AD :

$serviceprincipal = Get-AzureRmADServicePrincipal -SearchString $webAppName
New-AzureRmADGroup -DisplayName $adGroupName -MailNickName $adGroupName | Add-AzureRmADGroupMember -MemberObjectId $serviceprincipal.Id

La suite se passe sur la base de données, où on ajoute en SQL le groupe en tant qu’utilisateur :

CREATE USER [Nom_du_groupe] FROM EXTERNAL PROVIDER

On donne ensuite les droits nécessaires à cet utilisateur. Dans cet exemple, l’application n’a qu’un droit de lecture :

ALTER ROLE db_datareader ADD MEMBER [Nom_du_groupe]

N’oubliez pas que sur l’environnement de développement, il faut également vous donner les droits sur la base de données pour lancer l’application localement. De la même manière qu’avec Key Vault, il faut lancer la commande CLI pour être authentifié.
Voici le code C# qui permet de se connecter à la base de données par authentification MSI. Le package nuget Microsoft.Azure.Services.AppAuthentication doit être installé :

string connectionString = "Data Source=<AZURE-SQL-SERVERNAME>; Initial Catalog=<DATABASE>;";
using (var connection = new SqlConnection(connectionString))
{
      var tokenProvider = new AzureServiceTokenProvider();
      connection.AccessToken = await tokenProvider.GetAccessTokenAsync("https://database.windows.net/");
      connection.Open();
}

Ainsi, une connexion est ouverte sur le base de données, votre application peut y accéder et effectuer les opérations permises par les droits qui ont été donné au groupe AD.

Conclusion

Si vous avez déjà développé des applications qui doivent accéder à des ressources Azure, vous connaissez probablement les applications enregistrées (App registered) et l’utilisation d’identifiants pour accéder à ces ressources : Client Id et Secret ou certificat. Vous pouvez voir qu’avec MSI, c’est le même fonctionnement mais sans avoir à utiliser d’identifiants. Ce qui amène plus de sécurité dans votre système.

Nous avons vu 2 exemples ici, mais il est possible d’accéder à différentes ressources telles que Data Lake Store ou compte de stockage, depuis une fonction Azure ou une VM.

0 commentaires

Soumettre un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Découvrez nos autres articles

Aller au contenu principal