Dans le post précédent, on a vu qu’il était possible de déléguer l’authentification de notre application à WAAD, via de la fédération passive :

https://sebastienollivier.fr/blog/azure/authentification-via-windows-azure-active-directory-production/

Après que l’utilisateur se soit authentifié, la liste des claims renvoyée sera la suivante (la liste peut légèrement différer en fonction de la configuration de votre WAAD) :

Liste des claims

Pour pouvoir récupérer d’autres claims (rôles, groupes, etc.), on ne va pas pouvoir passer directement par WAAD (comme on pourrait le faire en configurant ACS ou ADFS) mais on va devoir s’appuyer sur les Graph Api. Les Graph Api sont des API REST exposant les objects Active Directory pour un tenant donné.

On va voir dans ce post comment récupérer des informations de l’utilisateur connecté depuis WAAD.

Déclaration des droits de l’application sur WAAD

Dans le post précédent, on a dû enregistrer notre application sur WAAD, via le portail Azure.

Avant de rentrer dans le vif du sujet, il va falloir qu'on s'assure d'avoir donné les droits de lecture (voire d'écriture) sur les Graph API à notre application. Pour cela, on va retourner sur le portail, et plus précisement sur l'application que nous avons enregistrée.

Le bouton Manage Access va permettre de modifier les droits d'accès de l'application :

Manage Access

Cliquez sur Change the directory access for this app pour sélectionner le niveau de droit :

Manage Access Wizard

Vous pouvez sélectionner un droit en fonction des actions que vous souhaitez effectuer :

Directory Access

L'application a maintenant le droit d'accéder aux Graph API. Il faut ensuite créer une clef qui permettra d'authentifier l'application auprès des API.

Dans l'onglet Configure, la zone Keys liste les clefs de l'application. Pour en créer une, il suffit de sélectionner une durée puis d'enregistrer :

Application keys

On peut maintenant authentifier l'application via cette clef, il ne nous reste plus qu'à requêter le service.

Requêtage des Graph API

Comme on l'a vu, les Graph API sont des services REST. Avant de pouvoir communiquer avec eux, il va falloir récupérer un token depuis ACS pour notre tenant et notre application. Ce token devra ensuite être envoyé dans chaque requête aux Graph API.

Pour faciliter le travail, Microsoft a développé un helper qui encapsule toute la mécanique d'authentification. Vous pouvez trouver le projet ici : http://code.msdn.microsoft.com/windowsazure/Windows-Azure-AD-Graph-API-a8c72e18

Pour récupérer un token, il faut appeler la méthode statique GetAuthorizationToken de la classe DirectoryDataServiceAuthorizationHelper en renseignant le nom du tenant, l'id de l'application ainsi que la clef que l'on a créé précédemment.

var token = DirectoryDataServiceAuthorizationHelper.GetAuthorizationToken(
                                 "sebastieno.onmicrosoft.com", 
                                 "http://localhost/Sor.GraphApi/",
                                 "xxx");

En retour de cette méthode, on va recevoir le token. A partir de là, on va pouvoir créer une nouvelle instance de la classe DirectoryDataService en passant le nom du tenant et le token récupéré.

var dataService = new DirectoryDataService("sebastieno.onmicrosoft.com", token);

Cette classe expose un ensemble de DataServiceQuery représentant les différents objets AD exposés par les Graph API. Pour récupérer l'utilisateur connecté à partir de son UPN, on doit utiliser la syntaxe suivante :

ClaimsIdentity identity = (ClaimsIdentity)HttpContext.User.Identity;

var upn = identity.Claims.First(claim => claim.Type == ClaimTypes.Name);

var user = dataService.users.Where(u => u.accountEnabled == true && u.userPrincipalName == upn.Value)
   .AsEnumerable()
   .SingleOrDefault();

Pour récupérer les rôles de l'utilisateur, il suffit alors d'écrire :

var roles = dataService.LoadProperty(user, "memberOf").OfType<Role>();

Plutôt simple !

On pourrait créer une surcharge de ClaimsAuthenticationManager en overridant la méthode Authenticate qui irait chercher les rôles de l'utilisateur (en utilisant le code précédent) et qui les rajouterait à l'identité HttpContext.User.Identity en tant que claim de type Role. De cette manière, on pourra utiliser les attributs Authorize et la méthode IsInRole de manière classique dans toute l'application.

Bon requêtage !

Si cet article t'a plu, n'hésites pas à partager , et si tu as des questions / remarques, n'hésites pas à me contacter