Archives de catégorie : postman

Resource Group As a Service–Enfin l’heure de consommer les API

Après un billet d’introduction et quatre pour la mise en œuvre, il serait peut-être temps de conclure et d’exploiter les API mises à disposition. Pour rappel, notre seconde instance du service Azure Function propose les API suivantes :

 

Avant de pouvoir commencer à consommer, on doit préparer un peu le terrain pour Postman. Pour ceux qui ont suivi le billet Authentifiez vos Azure Function avec Azure AD, ils sauvent que c’est l’heure de la construction des paramètres. Commençons par mettre en place une clé pour Postman au niveau de notre application Azure AD. Ce sera notre secret à consommer depuis Postman.

clip_image001

 

Ensuite, récupérons l’identifiant unique de notre tenant Azure AD (Aka TenantID) avec la commande PowerShell suivante : Get-AzureADCurrentSessionInfo | Format-List

clip_image002

 

Prochaine étape avec l’identifiant unique de notre application Azure AD ainsi que l’URL de Callback pour le retour à Azure Function après authentification. Nous obtiendrons ces deux informations avec la commande PowerShell suivante : Get-AzureRMADApplication -DisplayNameStartWith resourcegroupasaservicepublicapi

clip_image003

 

Maintenant, c’est l’heure de consommer.

 

API Get-AuthorizedSubscriptions

Testons avec la première API : Get-AuthorizedSubscriptions depuis Postman. Pour chaque API, nous allons configurer la méthode d’authentification OAuth 2.0

clip_image005

 

Pour les paramètres, je vous renvoie vers le billet Authentifiez vos Azure Function avec Azure AD. Avec tout cela, on devrait être en mesure de demander un jeton en cliquant sur le bouton Get New Access Token.

clip_image006

 

Normalement, cela devrait nous rediriger vers une mire d’authentification Azure AD. Si tout se passe bien, Azure AD rendra la main à notre application Azure AD via la CallBack URL.

clip_image008

 

Après authentification, on devrait obtenir une interface comme illustré ci-dessous avec un Token que nous allons consommer avec le bouton « Use Token ».

clip_image009

 

Attention, le token obtenu est valable une heure. Passé ce délai, il faudra penser à un demander un nouveau. Si tout se passe bien, notre API Get-AzureAuthorizedSubscriptions devrait finir par nous répondre avec une liste de GUID qui sont en fait la liste des souscriptions qui me sont autorisés pour utiliser le service.

clip_image011

 

Derrière l’appel à l’API nous avons une Azure Function. On peut constater la trace de l’appel à la fonction

clip_image013

 

En fait, quand on regarde le contenu de la table AuthorizedCallers, on comprend que la fonction a récupéré l’identité de l’appelant et recherché si l’utilisateur était autorisé ou non.

clip_image015

 

Dans mon contexte, on comprend que mon compte est autorisé à demander la création de groupes de ressources dans deux souscriptions Azure.

API Get-AuthorizedEnvironments

Chaque utilisateur autorisé sur une souscription est associé à un ou plusieurs environnements. Au final, ce sera un tag sur le groupe de ressources qui sera créé. Côté API, elle attend un paramètre : un identifiant unique de souscription. Ça tombe bien, c’est justement ce que la précédente API nous avait retourné. L’API attend un paramètre nommé SubscriptionID.

clip_image017

 

La demande initiée, on doit pouvoir constater le traitement dans Azure Function. A la lecture des logs, on constate que l’appelant serait autorisé à utiliser une seule valeur pour le tag Environnement.

clip_image019

 

De retour dans Postman, on constate bien que l’appelant pourra uniquement demander la création de groupes de ressources tagués TESTS pour la souscription donnée. Toute demande de création pour un autre environnement sera automatiquement rejetée.

clip_image021

 

API Get-AzureAuthorizedRegions

Resource Group As a service permet de limiter les régions Azure pour la création des groupes de ressources. Quelque part, c’est un peu le rôle de Azure Policy me direz-vous ? Oui mais Azure Policy est intégré à ARM qui n’a aucune idée de qui réalise le déploiement. L’API Get-AzureAuthorizedRegions permet de répondre à cette problématique. Chaque utilisateur accrédité pour une souscription donné est limité à une liste de régions Azure donnée. Logiquement l’API attend un identifiant unique de souscription Azure pour répondre à la question. En retour, nous sommes informés des régions Azure dans lesquelles nous sommes autorisés à demander la création d’un groupe de ressource dans la souscription Azure indiquée en paramètre.

clip_image023

 

Côté Azure Function, on peut voir le déroulement de l’exécution.

clip_image025

 

API Get-AuthorizedCostCenters

Resource Group As a Service contribue à la maitrise des coûts. Chaque groupe de ressources qui sera créé se verra assigné un tag CostCenter. Chaque utilisateur autorisé pour une souscription donnée est associé à une liste de valeurs autorisées pour ce tag. Encore une fois, il faut préciser la souscription Azure pour laquelle on veut connaitre les valeurs du tag qui nous sont autorisées.

clip_image027

 

En retour, on obtient. On une liste des valeurs que l’on pourra utiliser pour demander la création de notre groupe de ressources.

 

API Request-ResourceGroup

On a enfin tous les paramètres pour demander la création d’un groupe de ressources. C’est le rôle de l’API Request-ResourceGroup. A ce niveau, on a un peu plus de monde dans la section Body. En fait, on retrouve beaucoup des informations que nous avons déjà abordées :

  • ResourceGroupName : Pas la peine d’expliquer
  • Region : La région Azure dans laquelle créer le groupe de ressources (doit être autorisée)
  • ProjectName : Tag optionnel
  • SubscriptionID : Pas la peine d’expliquer
  • Environment : Une des valeurs qui nous sont autorisées
  • Backup : Tag optionnel
  • CreatedOn : Tag optionnel
  • SLA : Tag optionnel

 

clip_image029

 

Il faut être un peu patient, entre l’authentification, la création du groupe de ressources et la mise en place des tags, ce n’est pas instantané mais 14 secondes, c’est pas cher payé quand on a toute une équipe de développeurs qui attend la création d’un groupe de ressources pour travailler (je ne parle même pas du TJM cumulé, …).

clip_image031

 

Le résultat

Au final, ce qui nous intéresse, c’est quand même le résultat. Jusqu’à maintenant, on est capable de déclencher la création d’un groupe de ressources dans une souscription Azure.

clip_image001[1]

 

En regardant d’un peu plus près, on retrouve même tous les tags demandés. Pour certains, il y a même eu interprétation (CreatedOn, Owner, …)

clip_image002[1]

 

Pourtant, il y a un truc qui manque, les permissions. C’est là ou Resource Group As a Service a besoin de nous. Si on ne lui dit rien sur ce sujet, il ne fera rien. Par contre, si on lui communique les bonnes indications dans la table AuthorizedIAMTemplateRole, ça changera du tout au tout. Le contenu attendu est le suivant :

  • PartitionKey : L’identifiant unique de votre souscription
  • RowKey : Guid unique au sein de la Partition Key
  • Azure AD Group : Groupe Azure AD qui sera utilisé pour assigner un rôle
  • Role : Nom du Rôle Builtin / custom à assigner au niveau du groupe de ressources
  • Environment : Valeur du tag Environnement

 

Chaque ligne dans la table AuthorizedIAMTemplateRole représente donc une assignation de rôle Builtin / custom pour un environnement donné et une souscription donnée.

C’est grâce à cela que Resource Group As a Service prend tout son intérêt. Les permissions positionnées sur le groupe de ressources dépendront de la valeur du tag Environnment utilisée par le demandeur. Ce qui manque, c’est quelques entrées dans une table Azure. Easy en quelques lignes de PowerShell :

$RGName = « <Groupe de ressources contenant le Storage Account contenant les tables> »

$storageAccountName = « <Nom du storage Account> »

$SubscriptionID = « <Azure Subscription ID> »

$AuthorizedIAMTemplateRoleTableName = « AuthorizedIAMTemplateRole »

$keys = Get-AzureRmStorageAccountKey -ResourceGroupName $RGName -Name $storageAccountName

Import-Module -Name AzureRmStorageTable

$IAMTable = Get-AzureStorageTableTable -resourceGroup $RGName -tableName $AuthorizedIAMTemplateRoleTableName -storageAccountName $storageAccountName

Add-StorageTableRow -table $IAMTable -partitionKey $SubscriptionID -rowKey (new-guid).guid -property @{« AzureADGroup »= »GROUPE »; « Environment »= »TESTS »; »Role »= »Reader »}

clip_image003[1]

 

Si on recommence la création du groupe de ressources, on pourra alors constater qu’il y a bien un assignement de rôle qui a été réalisé pour le groupe Azure AD indiqué et le groupe de ressources nouvellement créé.

$AdGroup = Get-AzureADGroup -SearchString GROUPE

Get-AzureRMRoleAssignment -ObjectID $groupe.ObjectID

clip_image004

 

Maintenant Resource Group As a Service prend tout son sens.Si vous êtes arrivés jusque-là, c’est que votre implémentation manuelle de Resource Group As a Service est opérationnelle, félicitations. Pour les plus fainéants, la prochaine version sera 90% industrialisée et comprendra le déblocage de quelques features actuellement cachées.

 

Benoît – Simple and secure by design but business compliant.

Authentifiez vos Azure Function avec Azure AD

De retour sur Azure Function. Après avoir exploré les possibilité d’intégration entre Azure Function et Azure API Management, revenons dans Azure Function avec un aspect sécurité. Comment sécuriser l’accès à vos API? Techniquement, Azure API Management nous propose ce type de service avec la capacité de supporter de multiples fournisseurs, cependant lorsqu’on a qu’une seule Azure Function à exposer, ça fait un peu lourd et cher. On va donc voir ce que nous propose App Service out of the box que nous allons aborder en plusieurs étapes :

  • Mise en place des fondations
  • Prise en charge de l’authentification Azure AD
  • Bonus : Postman

 

Mise en place des fondations

La première chose dont on va avoir besoin, c’est effectivement d’une instance du service Azure Function. Jusque-là, rien de bien compliqué.

clip_image001

De là, il ne nous reste plus qu’à mettre en place notre Azure Function à sécuriser. Celle-ci sera configurée sans authentification. Elle sera donc librement accessible à toute personne connaissant l’URL. La fonction d’authentification sera déportée dans Azure AD plus tard.

clip_image002

 

Pour finir notre mise en place, on a juste besoin d’une petite dose de code, de PowerShell en fait. Ce qu’il faut comprendre, c’est que Web App sui sert de socle à Azure Function va faire la majorité du travail pour nous. Tout ce que nous attendons, c’est l’identité de l’utilisateur connecté que nous allons retrouver dans les Server Variables dans notre session. Ce que va faire Azure Web App, c’est peupler des variables pour nous dont la variable « HTTP_X_MS_CLIENT_PRINCIPAL_NAME ». Attention, nous allons n’avoir que l’identité de l’appelant à notre Azure Function pas le claims obtenu (un peu plus de travail). En PowerShell, c’est aussi simple que cela :

$requestBody = Get-Content $req -Raw | ConvertFrom-Json

$result = Get-Variable -name REQ_HEADERS_X-MS-CLIENT-PRINCIPAL-NAME -ErrorAction SilentlyContinue

if ($result.name -ne $null)

{

Out-File -Encoding Ascii -FilePath $res -inputObject « Hello $($result.value) »

}

else

{

Out-File -Encoding Ascii -FilePath $res -inputObject « Unauthenticated. »

}

 

On peut tester immédiatement, l’authentification Azure AD n’étant pas encore en place, la variable n’existe pas pour l’instant. D’où le retour « Unauthentified ».

clip_image003

 

Prise en charge de l’authentification Azure AD

C’est maintenant que les choses se compliquent. On a bien une fonctionnalité « Authentication / Authorization ». Activer la fonctionnalité va impacter toutes les Azure Functions qui sont portées par l’instance de notre service.

clip_image004

 

Activer la fonctionnalité, c’est ce qu’il y a de plus simple. On va donc forcer l’authentification pour toutes les connexions et indiquer que nous allons utiliser le fournisseur Azure Active Directory.

clip_image005

 

Pour les besoins de la démonstration, on sa se contenter de la configuration Express. Maintenant challenge : avez-vous le privilège Administrateur général au niveau AD ? Si oui, alors on peut créer immédiatement l’application (et le service principal associé). Dans le cas contraire, il faudra demander à celui qui détient les droits de gérer cela pour vous pour ensuite sélectionner l’application Azure AD nouvellement déclarée. Dans notre contexte, je dispose des privilèges, on continue.

clip_image006

 

Ne surtout pas oublier de sauvegarder la configuration.

clip_image007

 

Derrière, on sait tout de suite que cela fonctionne, il suffit de tenter de réexécuter notre Azure Function. Il est clairement indiqué que l’authentification bloque l’utilisation du débugger.

clip_image008

 

Revenons sur la configuration de cette application déclarée dans Azure AD. Nous allons accorder à notre application des permissions déléguées pour autoriser l’authentification des utilisateurs et ne surtout pas oublier de sauvegarder la configuration.

clip_image009

 

Le message d’avertissement nous indique que dans la configuration actuelle aucun utilisateur de Tenant Azure Active Directory n’a accès à cette application. On a deux choix :

  • Une assignation manuelle pour chaque utilisateur ou collective (bouton Grant permissions)
  • Une assignation selon appartenance de groupe (Pas disponible avec une SKU Free d’Azure AD)

 

On va donc procéder à une activation massive pour tous les utilisateurs de notre Tenant Azure AD, que ceux-ci soient des utilisateurs dépendant du tenant ou simplement invités.

clip_image010

 

De là, on peut tester immédiatement (si on n’a pas limité le verbe GET dans notre Azure Function) en appelant simplement d’Azure Function depuis notre navigateur. Si nous avons été préalablement authentifiés, notre token sera utilisé. Sinon, une mire d’authentification nous sera proposée.

clip_image011

 

Bonus : Postman

Pour le bonus, pas de PowerShell. En fait, j’ai découvert qu’obtenir un token Oauth2 et le soumettre pour négocier un token pour s’authentifier auprès de notre Azure Function est à ce jour d’une complexité incroyable. Je me suis donc mis en quête d’une méthode plus simple pour tester mon Azure Function : Postman. C’est un client REST qui a pour avantage de prendre en charge Swagger pour générer la documentation associée à note API.

Avant de rentrer dans Postman, nous allons collecter quelques informations nécessaires. La première est l’identité de notre application Azure Active Directory. Celle-ci utilise l’identité d’un Service Principal (équivalent d’un compte de service). On va commencer par collecter l’identifiant unique de notre application déclarée dans Azure.

clip_image012

 

Passons à la suivante avec un peu de PowerShell pour retrouver l’identifiant unique de notre Tenant Azure Active Directory dans l’attribut TenantID :

$cred = get-credential

Connect-AzureAD -Credential $Cred

Get-AzureADCurrentSessionInfo | fl

clip_image013

 

Continuons en PowerShell en récupérant la ReplyURL de notre application enregistrée dans Azure Active Directory : Get-AzureRMADApplication -DisplayNameStartWith authenticatedaz

clip_image014

 

Maintenant, un peu de construction :

Retournons au niveau de notre application publiée dans Azure. Nous avons besoin de générer un secret qui sera utilisé lors de l’authentification. Pour les besoins de la démonstration, nous allons générer ce secret sans date d’expiration. La bonne pratique consiste à renouveler ces secrets régulièrement et bien sûr de ne pas partager un même secret entre plusieurs applications. Attention à copier la clé générée avant de quitter l’interface. Après-cela, elle ne sera plus divulguée.

clip_image015

 

Maintenant, tout se passe dans Postman. Si on tente le direct, on va clairement nous répondre que nous ne sommes pas autorisés.

clip_image016

 

En fait, on a besoin de construire une authentification Oauth2.

clip_image017

 

Ci-dessous la configuration à utiliser avec quelques explications :

  • Token name : Your choice
  • Grant Type : Authorization Code
  • CallBack URL : Celle que nous avons collectée
  • Auth URL : Celle que nous avons générée
  • Client ID : C’est l’Application ID de notre application (ne cherchez pas ClientID dans le portail, ça sert à rien)
  • Client Secret : Normalement, vous l’avez conservé
  • Scope : Inutile dans notre cas
  • State : Inutile dans notre cas
  • Client Authentication : Send client credentials in Body

 

clip_image018

 

Ne reste plus qu’à cliquer sur « Request Token » pour obtenir notre Access Token. Une mire d’authentification Azure AD nous sera proposée. Attention, dans la configuration par défaut d’Azure AD, la durée de vie est d’une heure. Après, c’est personnalisable : Configurable token lifetimes in Azure Active Directory (Public Preview). Et cela fonctionne.

clip_image019

 

C’est une utilisation très basique de Postman car l’outil va bien plus loin que cela, en particulier pour réaliser des tests unitaires, voire même des tests automatiques.

Benoît – Simple and secure by design but business compliant