Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

Protéger une application avec Azure AD

Poster un commentaire

Protéger une application avec Azure AD permet d’imposer un mécanisme d’authentification pour y accéder.

Cet article sera suivit d’un second consacré à la connexion vers une Web Api protégée à partir de divers clients.

Je vais développer ici:

  • quelques révisions sur OAuth2
  • Comment créer et déployer une application avec authentification grâce à Visual Studio
  • Comment enregistrer une application dans Azure AD
  • Comment récupérer les configurations dans Azure AD
  • Comment mettre en place un middleware d’authentification OpenId Connect

Les protocoles supportés et quelques généralités

protocoles

Azure AD supporte un certain nombre de protocoles pour sécuriser nos applications:

  • WS-Federation
  • SAML-P
  • OAuth 2.0
  • OpenId Connect

J’ai déjà tracé un descriptif (dans une perspective historique) de ces protocoles:

https://amethyste16.wordpress.com/2016/03/07/levolution-des-methodes-dauthentification/

Pour la suite je vais surtout faire appel à OpenId Connect pour s’authentifier et OAuth2 pour gérer les autorisations.

 

Note: Si Federation vous intéresse, j’ai fais jadis un article démontrant l’utilisation de WS-Federation:

https://amethyste16.wordpress.com/2014/11/07/lauthentification-ws-federation-avec-azure-windows-active-directory/

 

Points de terminaison

On accède à ces protocoles via un point de terminaison. Les points de terminaison sont de la forme:

https://<instance>/<tenantId>/<protocole&gt;

 

Instance représente l’instance publique d’Azure AD dans lequel le tenant est déployé. La plupart du temps il s’agit de:

login.microsoftonline.com

Mais pas toujours. Dans le temps il s’agissait de:

login.windows.net

 

D’autres déploiements existent, par exemple en Chine on trouvera:

login.partner.mirosoft.online.cn

Dans ce pays Azure est complètement isolé du reste du monde. Je ne suis même pas certain que Microsoft y possède ses data centers.

 

TenantId est un identifiant unique associé à notre AD. Il est représenté au choix  par:

  • un guid
    Un guid présente l’avantage de la pérennité, mais de là à s’en rappeler…
  • le nom du tenant
    le nom DNS du tenant qui est soit celui donné par défaut par Azure. En général il s’agira d’une adresse de la forme:
    <nom tenant>.onmicrosoft.comLe nom du tenant ou du domaine personnalisé donne une adresse nettement plus conviviale. Mais elle n’assure pas de pérennité.
  • un domaine personnalisé

On verra plus loin comment récupérer ce paramètre et d’autres d’ailleurs.

 

La partie protocole dépend du protocole ciblé. Par exemple pour OAuth2 on aura:

https://login.windows.net/123aze852fgy/oauth2

 

Petits rappels OAuth2

J’ai fais une présentation de l’architecture générale d’un système de gestion des autorisations basé sur une fédération:

https://amethyste16.wordpress.com/2014/11/25/lauthentification-federee-par-claims-les-grands-principes/

Azure AD met une telle architecture à notre disposition. Je n’y ai pas spécialement parlé d’OAuth, mais les protocoles présentés sont ceux là même que nous allons mettre en œuvre. Il est donc important de relire cet article avant de passer à la suite, mais tout dépend du niveau de compréhension que vous souhaitez acquérir.

 

Pour l’essentiel OAuth2 n’est pas tant un protocole d’autorisation qu’un protocole de délégation. L’idée est similaire à celle d’une clef voiturier de certaines voiture de luxe. Vous pouvez donner une clef à un voiturier qui va se charger de certaines opérations en votre nom comme garer la voiture.

Toutefois vous gardez la main sur tout: vous contrôler par exemple la distance ou la vitesse qu’il peut parcourir, l’accès ou non à certaines partie du véhicule comme la boîte à gant et vous pouvez révoquer la clef. Le voiturier a une délégation sur une partie de vos ressources, mais pas tout et il n’a jamais accès à vos mots de passe.

OAuth va implémenter une idée similaire. Pour y parvenir OAuth désigne 4 acteurs:

  1. Le propriétaire de la ressource (resource owner)
    En général c’est vous, en tout cas un utilisateur. Vous disposez de tous pouvoir sur la ressource
    Dans notre contexte
  2. La ressource à protéger (protected resource)
    Comme l’indique son nom. Dans l’exemple il s’agit de la voiture, mais dans le contexte de cet article ce sera plutôt une API.
  3. le client
    Le code qui souhaite accéder à la ressource.
    Il ne s’agit pas forcément d’une application Web.
  4. Le serveur d’autorisations (authorization server)
    Le serveur responsable de la gestion des autorisations.
    On le notera AS par la suite.

 

Le scénario le plus typique mettant en œuvre ces 4 acteurs est le suivant:

 

Note: J’ai réalisé ce schéma avec un étonnant outil: https://www.websequencediagrams.com/

On notera que l’on se connecte deux fois sur l’AS, à chaque fois avec un point de terminaison spécifique:

 

Dans un cas on obtient un code et dans l’autre un jeton d’accès (access token) à partir du code ainsi qu’un jeton de renouvellement.

 

Ce scénario est un des 4 scénarios d’authentification définis par OAuth2. Il s’agit du plus utilisé, en tout cas celui conseillé chaque fois qu’il s’applique.

Vous pouvez trouver des infos sur les autres scénarios soit dans la RFC:

https://tools.ietf.org/html/rfc6749#page-8

Soit dans ce petit tuto en français:

http://www.bubblecode.net/fr/2016/01/22/comprendre-oauth2/

 

… soit dans les deux articles qui vont suivre!

 

Une des étapes clef de ce scénario est l’existence d’une redirection vers l’AS. Evidemment cela suppose que le client puisse gérer cette redirection. Pas de problème pour une appli web, mais c’est moins évident pour les applications natives. C’est pour résoudre ce genre de difficultés qu’OAuth2 propose d’autres scénarios. Nous verrons des cas concrets plus loin.

Autre point, le plus souvent l’AS et le service hébergeant les ressources protégées sont les même. Donc 4 acteurs logiques, mais 3 physiques.

 

Important

Le point important à observer est l’étape de redirection vers l’AS. C’est à ce moment que l’utilisateur va saisir ses credentials et confirmer qu’il donne accès aux ressources réclamées. Le client ne reçoit qu’un jeton et ne voit donc jamais les credentials. C’est le point important de la chaîne de sécurité proposée par OAuth2 qui le diffère des modèles plus anciens dans lesquels l’application cliente proposait un formulaire de login/mot de passe.
OAuth2 garantit donc qu’à aucun moment le client ne pourra enregistrer ou usurper vos identifiants puisqu’il ne les verra jamais.

 

Pour finir une différence importante avec OAuth 1.0 est qu’OAuth 2 sous-traite la partie sécuritaire à TLS. On devra donc obligatoirement activer une connexion HTTPS pour nos sites.

La méthode rapide

Créer et configurer l’application

Visual Studio peut configurer automatiquement une application Web ou Web Api et faire les inscriptions directement dans Azure. Elle est prête à l’emploi, il n’y a qu’à faire F5.

 

Le prérequis est bien entendu de disposer d’un compte Azure. Vous en avez peut-être un sans le savoir, essayez de vous connecter au portail avec un compte d’entreprise:

https://portal.azure.com

 

Important: Vous n’aurez pas besoin d’être administrateur. Par défaut, tous les comptes peuvent inscrire dans Azure AD une application.

C’est vrai uniquement depuis un client enregistré. Hors ce n’est a priori pas le cas de VS. J’ai trouvé ici une explication qui en gros est: VS est en enregistré d’une façon spéciale qui lui permet de faire ce genre de choses.

 

  • Lancer Visual Studio
  • Créer un projet ASP.NET MVC classique, CORE est très peu différent pour ce qui concerne ce tutoriel

C’est ici que c’est important:

Sélectionner Change Authentication:

Faites les sélections comme présentées sur la copie d’écran (Work or School Accounts). En (3) sélectionnez le tenant Azure sur lequel vous souhaitez inscrire l’application une fois que VS en aura récupéré la liste complète.

 

Le type de compte s’appelait jadis « Organizational Account« . Si vous avez besoin d’infos supplémentaires:

https://amethyste16.wordpress.com/2016/10/13/gerer-les-ressources-azure-au-niveau-utilisateur-avec-azure-ad/

 

Important: Ne pas oublier de configurer le site en HTTPS. On se rend dans les propriétés du projet:

Une fois la propriété basculée à true, une Url SSL est alimentée (voir ci-dessus).

Tester l’application

La première fois que l’on lance HTTPS avec IIS Express, on voit s’afficher:

 

On accepte puis on continue.

La suite est identique à ce que j’ai déjà présenté dans un précédent tuto où je propose une étude complète de l’authentification avec VS:

https://amethyste16.wordpress.com/2014/08/23/mettre-en-place-lauthentification-avec-visual-studio-2013-partie-ii/

 

Ce qui a changé est que maintenant le nouveau portail propose un support d’Azure AD (encore en préview). Celui qui a été aperçu dans le paragraphe précédent:

On constate que l’application a bien été enregistrée auprès d’Azure AD.

On s’en doutait un peu d’ailleurs, car sinon qui aurait géré la séquence d’authentification enclenchée lors du lancement de l’application?

Un autre compte

Peut t’on se connecter avec un autre compte que le compte administrateur? Oui bien entendu, la preuve est que nous allons essayer.

On se rend dans le portail:

On sélectionne User and Groups, puis All users.

Puis ADD:

On a plusieurs options. On peut créer un compte Work or Student Account, c’est à dire un compte dans Azure AD ou bien inviter quelqu’un dont on connaît l’émail. Choisissons la deuxième option:

Au bout de quelques instant on reçoit un mail avec toutes les infos pour configurer le compte:

On clique sur le lien, le reste est du NEXT. Je suis arrivé ici:

Ce que confirme le portail:

On lance ensuite l’application.

Vous devriez pouvoir vous authentifier avec ce compte.

 

La première option n’est pas plus compliquée, la procédure est identique, il suffit juste de saisir un nom de la forme:

<NOM>@<TENANT DOMAIN>.onmicrosoft.com

Par exemple le domaine de mon tenant est fmirouzehotmail, je pourrais donc créer:

amethyste@fmirouzehotmail.onmicrosoft.com

On en profite pour récupérer le mot de passe auto généré. Lors de la première connexion il vous sera demandé de le modifier.

Pour obtenir le domaine de votre tenant: https://amethyste16.wordpress.com/2017/07/14/comment-trouver-lid-de-son-tenant/

 

Maintenant que ceci est acquis, entrons dans le sujet en faisant tout artisanalement.

Ajouter une application à Azure AD

Nous allons cette fois configurer une application à la main dans Azure. Cette étape est indispensable pour que l’application puisse s’appuyer sur Azure AD afin de gérer son authentification.

Que votre application soit une application Web ou une application native, la procédure générale est la même. Il existe toutefois quelques différences mineures que je soulignerai dans le texte.

Cas général

Dans le portail on se rendre dans le menu « App Registration » après avoir choisit le tenant Azure qui gère les utilisateurs qui pourrons se connecter à l’application. Le formulaire est celui présenté juste au dessus.

Cliquer sur ADD:

  • Name
    Nom sous lequel l’application apparaîtra dans la liste des applications Azure AD
    Le nom doit faire au-moins 4 caractères
  • Application Type
    On doit indiquer le type d’application qui sera enregistrée.Deux possibilités sont offertes:
    Web app/API
    NativeLa démo suivante portera sur une application console, il s’agit donc d’une application native. C’est l’option qui sera choisie.Ce choix est important car il détermine des possibilités offertes à l’appli en terme de processus d’authentification.
    Par exemple, une application web peut être le destinataire de jetons émis par l’intermédiaire de protocoles basés sur la redirection comme SAML ou OpenID, mais pas une application native.
    Une application Web peut se voir assigner un secret, mais pas une application native pour les raisons que l’on devine.
    Une application native ne peut recevoir de permissions d’application
  •  Le dernier paramètre change de nom selon le choix de type d’application (voir ci dessous).
    On attend une valeur au format d’une url valide (donc en particulier commençant par un nom de protocole comme http!)
    Le point de terminaison ainsi définit n’a pas besoin d’exister réellement et dans notre cas c’est pas plus mal!

 

Regardez ce que raconte l’aide du portail au sujet de ce paramètre:

 

Ce texte est incorrect car le scénario mentionné n’est pas possible pour une application native à ma connaissance. De toute façon cela importe peu. Le point de terminaison n’a pas besoin de correspondre à quoi que ce soit de réel et ne sera de toute façon pas utilisé en tant que tel.

 

Si l’application était une application Web, on devrait entrer l’url sur laquelle l’utilisateur doit se connecter pour s’authentifier. En général la page d’accueil.

 

Cette url doit exister donc et est importante car c’est celle vers laquelle Azure AD va renvoyer les jetons. Si je reprends le cas de la première démo de cet article on saisirait SSL Url:

 

Note: quel que soit le choix réalisé, il pourra toujours être modifié plus tard ici:

 

Il est intéressant de voir à quoi les choses ressemble pour une application native:

 

 

Elle n’a pas même été sauvegardée!

 

Il existe une autre différence entre Native et Web application: App Id Uri

Le portail le génère automatiquement, mais on peut le modifier. Ce paramètre attend le format d’une url et doit être unique. dans le tenant. Ce paramètre est utilisé par certains protocoles comme SAML, OAuth2 ou WS-Federation. Mais même si on ne s’en sert pas (par exemple on utilise OpenID Connect), il est tout de même obligatoire de le renseigner.

 

A ce stade on doit voir apparaître l’application dans le formulaire:

 

Cas d’une application Web

Certains protocoles comme OAuth2 utilisent un secret que l’on appelle aussi Application Credential. Encore faut t’il le créer.

Dans notre situation un secret existe déjà. Pour en créer un nouveau on clique sur la zone Key Description et on saisit un nom. On choisit également une durée:

On clique ensuite sur SAVE:

 

Remarquez le bandeau orange qui signale que c’est la seule fois où la valeur sera affichée. Si vous avez besoin de ce secret, copiez le dès maintenant.

 

De par sa nature, il est évident qu’une application native ne devra jamais récupérer ce secret dans sa configuration.

Comment faire dans ce cas pour se connecter avec OAuth2 vers une Web API?

Je traiterai ce cas dans l’article qui suivra, mais la procédure est alors de créer un service qui renvoi un jeton valide qui pourra être ensuite présenté à la Web API. L’authentification au service de jeton peut se faire en OpenId Connect qui n’a pas besoin de ce secret.

Récupérer les configurations

On a besoin de récupérer certains paramètres pour notre application cliente. La liste dépend de sa nature et du protocole d’authentification choisit.

Voici tout de même ce qui pourrait nous intéresser:

Pour une console:

  • Application Id
  • Tenant Id

Pour une application Web:

  • Application Id
  • App Id URI
  • Le secret
  • Tenant Id

 

Application Id s’appelle aussi Client Id dans la littérature. Cet identifiant permet d’identifier l’application dans le contexte d’une authentification OpenId Connect.

On peut aussi le récupérer ici:

Le secret a été abordé dans le chapitre qui précède. Souvenez vous qu’il n’est possible de le récupérer qu’au moment où on le créée.

 

Tenant Id s’appelle aussi Directory Id dans le portail Azure.

La valeur du guid peut être obtenue par PowerShell ou depuis le portail.

En haut à droite repérez cette zone:

Cliquez dessus pour faire apparaître les différents tenants dont vous êtes membre et sélectionnez le.

Cliquez ensuite sur « More Services » en bas à gauche du portail:

Retrouvez Azure Active Directory:

On va s’intéresser au menu Properties:

Le formulaire suivant s’ouvre:

On récupère Directory ID. C’est le nom donné par le portail à Tenant Id. C’est la forme GUID de tenant Id.

 

On peut aussi avoir besoin des deux points de terminaisons de l’AS (Azure AD dans notre cas). On se rend dans le portail en sélectionnant le tenant qui nous intéresse:

On clique sur le menu ENDPOINT:

On récupère les deux points de terminaison si on en a besoin.

Le code d’authentification

On va prendre pour modèle le code généré par l’assistant utilisé dans le premier essai. L’essentiel se trouve dans Startup.Auth.cs qui implémente un middleware OWIN:

private static string clientId = ConfigurationManager.AppSettings["ida:ClientId"];
private static string aadInstance = ConfigurationManager.AppSettings["ida:AADInstance"];
private static string tenantId = ConfigurationManager.AppSettings["ida:TenantId"];
private static string postLogoutRedirectUri = ConfigurationManager.AppSettings["ida:PostLogoutRedirectUri"];
private static string authority = aadInstance + tenantId;
 
public void ConfigureAuth(IAppBuilder app)
{
   app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
 
   app.UseCookieAuthentication(new CookieAuthenticationOptions());
 
   app.UseOpenIdConnectAuthentication(
      new OpenIdConnectAuthenticationOptions
      {
         ClientId = clientId,
         Authority = authority,
         PostLogoutRedirectUri = postLogoutRedirectUri
      });
}

Je reparlerai des paramètres chargés en début de code plus loin dans cet article.

Le code est très simple, pour l’essentiel il rajoute 2 middlewares au pipeline OWIN:

  1. UseCookieAuthentication
    gestion du cookie d’authentification.
  2. OpenIdConnectAuthenticationOptions
    gestion de l’authentification OpenId Connect

Ces middlewares proviennent bien entendu de Nuget qu’il faudra ajouter à la solution:

  • Microsoft.Owin.Host.SystemWeb
    On a besoin d’ajouter le pipeline OWIN pour utiliser le nouveau SDK ASP.NET Identity qui apporte un support OAuth2 et OpenId Connect.
    J’ai fais une présentation rapide ici:
    https://amethyste16.wordpress.com/2014/08/15/lauthentification-en-asp-net-un-tour-dhorizon/
  • Microsoft.Owin.Security.Cookies
    La plupart des protocoles basés sur la redirection on besoin d’un jeton lors de la toute première connexion. Par la suite ils utilisent un cookie d’authentification. D’où la présence de ce middleware
  • Microsoft.Owin.Security.OpenIdConnect
    Implémentation de OpenId Connect. Parmi ses dépendances on remarque:
    System.IdentityModel.Tokens.JwtMême si le protocole est agnostique quand au choix du format de jeton, JWT est le choix le plus classique. Et je continue ma petite pub parce qu’il n’y a pas de raisons!!
    https://amethyste16.wordpress.com/2014/08/30/les-jetons-jwt-ce-quun-developpeur-doit-connaitre/

 

Autority est l’url racine vers le tenant Azure dont on accepte les utilisateurs. J’ai développé ce point dans le premier paragraphe de cet article.

ClientId est l’identifiant de l’application dans le tenant.

 

Note: l’ordre du code est important, sinon cela ne fonctionnera pas. Par exemple l’activation des cookies.

OpenIdConnect ne prévoit pas de notion de persistance, c »est donc à nous de l’apporter, ici via les cookies.
Il est donc important que cette déclaration de middleware se fasse très haut dans le pipeline OWIN, avant en tout cas qu’OpenIdConnect soit activé. Si vous entrez dans une boucle perpétuelle de réauthentification, le problème est sans doute là.

 

Pour finir, on n’oubliera pas de décorer les contrôleurs de l’attribut AuthorizeAttribute afin de déclencher le protocole d’authentification. Autrement rien ne se passe.

Et si je déploie dans un App Service?

Il n’y a rien de très différent mis à part un petit réglage à ajouter:

Il faudra rajouter l’url vers la page d’accueil dans la zone Reply Url, autrement Azure va vous renvoyer sur l’adresse en localhost avec le résultat que vous devinez.

 

Bibliographie

 

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s