Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

L’authentification WS-Federation avec Azure Windows Active Directory

Poster un commentaire

Dans un précédent article j’ai montré comment créer une application capable d’exploiter Windows Azure Active Directory (Waad):

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

Nous ne sommes pas vraiment allé voir fonctionner le code et nous sommes passé rapidement sur certains détails. Je propose de reprendre cet exemple, mais plus calmement et d’essayer de comprendre son fonctionnement.

Nous allons également voir comment on peut le simplifier considérablement avec OWIN.

 

Avant de lire la suite, il sera peut être profitable de lire l’article de présentation de Waad:

https://amethyste16.wordpress.com/2014/08/21/decouverte-de-windows-azure-active-directory-waad/

Ainsi que le tutoriel qui montre comment créer un tenant Azure:

https://amethyste16.wordpress.com/2014/08/19/provisionner-un-repertoire-azure-active-directory-waad/

Préliminaire

Bien entendu commencez par créer un tenant avant d’aller plus loin, puis créez une application comme indiquée dans le premier lien et testez là.

Si tout va bien vous devriez découvrir que l’assistant Visual Studio a enregistré l’application dans le tenant Azure comme un relying part (RP):

2014-11-03_22-20-20

Le code

Tout démarre avec des modules Http déclarés dans le fichier de configuration:

2014-11-04_08-16-40

  1. Chargement de deux modules Http de gestion des authentification
    SessionAuthenticationModule: création d’un cookie de session dans les scénarios d’authentification fédérée. On en reparlera plus loin
    WSFederationAuthenticationModule: sécurise l’application avec une authentification fédérée
  2. Déclaration des paramètres des deux modules. On trouvera la documentation ici:
    http://msdn.microsoft.com/fr-fr/library/vstudio/hh568674(v=vs.110).aspx

Le déclenchement de l’authentification se fait de façon très classique:

2014-11-04_08-11-23

Pour que cela fonctionne on a besoin de paramètres bien entendu. On en trouve une partie dans le fichier de configuration lui-même:

2014-11-03_22-23-431

  1. Des déclarations de section
  2. Des paramètres <appSettings>
  3. Une section <system.identityModel> dont on trouvera la documentation ici:
    http://msdn.microsoft.com/en-us/library/hh568638(v=vs.110).aspx

C’est verbeux, mais c’est ça WIF!

Il y a deux paramètres importants:

  1. ida:FederationMetadataLocation
    Cette valeur représente le tenant Azure ou bien l’instance ADFS sur laquelle l’utilisateur va s’authentifier
  2. ida:Realm
    Il s’agit de l’identifiant (unique) de l’application tel qu’on le retrouve dans le portail Azure ou ADFS. Dans les paramètres de configuration de l’application on trouve ceci:

2014-11-03_22-49-48

On peut aussi l’assigner dans l’assistant Visual Studio.

Cette valeur est celle envoyée au STS (Security Token Service), c’est à dire l’application chargée de gérer les jetons de sécurité, par exemple Azure AD.

Le préfixe ida est pour Identity anD Authorization.
Si on fait défiler le fichier de configuration jusqu’à <system.identityModel> on lit:

2014-11-04_07-21-36

La section <audienceUris> contient la liste des restrictions d’audience. Il s’agit des urls qui peuvent légalement être la cible d’une réponse du STS. En général on trouve une seule entrée, mais il peut y en avoir plus si l’application supporte plusieurs domaines.

La liste des audiences est en général envoyée au STS. S’il est présent, alors le STS le renseignera dans les paramètres du jeton.
Le client vérifie ensuite que le paramètre reçu est conforme à sa liste d’audience. Si ce n’est pas le cas le jeton est refusé.
On peut désactiver ce mécanisme à l’aide de l’attribut mode= »Never » de <audienceUris>.

On remarque un attribut ida:AudienceUri dans les AppSettings. Il s’agit de la valeur par défaut. Si elle n’est pas trouvée dans <audienceUris>, elle y sera rajoutée.

 

Bien entendu il faut du code pour charger ces réglages et créer l’environnement pour le module d’authentification. Si on se rend dans Application_Start(), on trouve la ligne suivante:

IdentityConfig.ConfigureIdentity();

Ainsi qu’un gestionnaire d’événement WSFederationAuthenticationModule_RedirectingToIdentityProvider.

Le gestionnaire d’événement est invoqué lorsque le module d’authentification redirige l’utilisateur vers le fournisseur d’identité.

La classe IdentityConfig est une classe utilitaire créée dans le projet par l’assistant VS et destinée à initialiser la plomberie d’authentification.

 

Comme on le voit, c’est peut être verbeux, mais pas bien difficile. Le module se charge de tout le travail.

Je pense que l’on a maintenant une vision suffisamment claire pour pouvoir mettre en place diverses personnalisation du scénario standard.

 

Mais on a plus qu’à oublier tout ça, car Owin simplifie considérablement les choses!

Simplifions avec OWIN

On va créer une application MVC sans authentification. Celle-ci sera ajoutée à la main.

Dans les propriétés du projet, activez SSL:

2014-11-04_23-03-01

Ca peut marcher sans, mais cela serait une mauvaise pratique.

Copiez l’url proposée dans SSL URL et copiez la ici:

2014-11-04_23-13-17

Cela garantie qu’en DEBUG on lancera l’adresse correcte, ce que vous pouvez tester en faisant F5.

Direction le portail Azure où vous attend votre tenant favori. On se rend dans l’onglet APPLICATION et on clique sur ADD:

2014-11-04_23-17-21

On sélectionne Add an application my organization is developing.

2014-11-04_23-19-25

On donne un nom à l’application. Je trouve bien de lui donner le même nom que le projet VS. Sélectionner Web application and/or web API.

2014-11-04_23-22-53

La première url est l’url SSL.

App ID URI a déjà été rencontré. Nous avons dit qu’il fallait fournir un identifiant unique dans le tenant au format d’une url. Cela peut être n’importe quoi qui a un sens pour vous, l’url n’a pas spécialement besoin de correspondre à quelque chose de réel.

Au bout de quelques instants ceci doit apparaître:

2014-11-04_23-26-17

L’application a été enregistrée dans le tenant. Elle peut s’authentifier auprès de lui.

 

Revenons au projet.

Ajoutez les packages Nuget:

  1. Install-Package Microsoft.Owin.Host.SystemWeb
  2. Install-Package Microsoft.Owin.Security.WsFederation
  3. Install-Package Microsoft.Owin.Security.Cookies

Le premier package installe la plomberie qui héberge le pipeline OWIN. Le deuxième ajoute la plomberie de gestion de l’authentification WS-Federation et le dernier le code qui gère les cookies dans notre contexte.

Ajoutez à la main où à l’aide de l’assistant la classe de démarrage OWIN:

2014-11-04_22-33-58

Important: vous devez installer cette classe dans le répertoire App_Start du projet. Si vous ne voulez pas le placer dans ce répertoire, il faudra compléter la classe avec cette déclaration (à adapter à votre contexte):

[assembly: OwinStartup(typeof(WebApplication1.Startup))]

 

Puis complétez là ainsi:

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.WsFederation;
using Microsoft.Owin.Security.Cookies;

namespace WebApplication1
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
            });

            app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions
            {
                MetadataAddress = "https://login.windows.net/DEFAULTDOMAIN.onmicrosoft.com/FederationMetadata/2007-06/FederationMetadata.xml",
                Wtrealm = "https://DEFAULTDOMAIN.onmicrosoft.com/WebApplication1",
            });
        }
    }
}

Vous devriez reconnaître les deux paramètres MetadataAddress et Wtrealm, sinon relisez le chapitre précédent. DEFAULTDOMAIN est le domaine par défaut de votre tenant et WebApplication1 est le nom de mon application.

On peut obtenir le MetadataAddress en se rendant sur l’onglet APPLICATION du tenant:

2014-11-04_22-50-47

On clique sur VIEW ENDPOINTS:

2014-11-04_22-54-11

Pour finir décorez vos contrôleurs avec l’attribut AuthorizeAttribute.

 

Lancez l’application. La mire de connexion doit s’afficher:

2014-11-05_23-04-26

Connectez vous, et l’application doit s’afficher.

Ca fonctionne donc comme avec l’assistant, mais cette fois avec très peu de code et rien dans le fichier de configuration.

Placez pour faire un test la ligne suivante sur l’action de démarrage et posez un point d’arrêt:

var principal = Thread.CurrentPrincipal;

Observons la propriété principal:

2014-11-06_22-32-39

On confirme tout d’abord que l’on est authentifié en WS-Federation. Regardez aussi le type des propriétés Principal et Identity: ClaimsPrincipal et ClaimsIdentity.

Nous ne sommes plus dans le schéma d’authentification habituel, mais en mode authentification par claims (revendications). Regardez la valeur des claims redescendus dans Result View. Le fournisseur d’authentification est le compte live.

 

Revenons un peu au code OWIN.

La première ligne m’a posé des problèmes car elle est mentionnée dans aucun des tutoriels que j’ai pu lire. Et pourtant sans elle on a un message d’erreur:

2014-11-06_22-39-07

Enfin presque aucun tutoriel.

En interne, cette ligne fait ceci, on change le nom du cookie d’authentification du middleware dans le contexte OWIN:

app.Properties["Microsoft.Owin.Security.Constants.DefaultSignInAsAuthenticationType"] = "ExternalCookie";

Le cookie est ensuite créé par la ligne qui suit.

Ce cookie d’authentification joue le même rôle que le cookie d’authentification lors de l’authentification classique. Ce cookie est le cookie que les applications externes d’authentification devront utiliser pour vous rediriger vers l’application cliente.

 

UseWsFederationAuthentication configure quand à lui l’authentification WS-Federation.

Déployer la version OWIN

Si vous déployez le site et tentez de vous connecter vous arriverez sur quelque chose de similaire à ceci:

2014-11-07_22-08-29

L’authentification ne fonctionne pas. Regardez l’url de retour, ce n’est pas celle attendue. Il faut modifier les paramètres dans le tenant.

On se rend dans l’onglet APPLICATION et on sélectionne l’application. On se rend ensuite dans l’onglet CONFIGURE.

2014-11-07_22-14-12

On remplace ajoute aux urls de retour (REPLY URL) l’url du site déployé:

2014-11-07_22-30-30

On a activé SSL, ne pas oublier de mettre HTTPS!

On n’oublie pas de sauvegarder:

2014-11-07_22-19-47

Cette fois la connexion devrait fonctionner.

Important: l’ordre des urls est important. L’url de de retour sera par défaut la première trouvée dans la liste. C’est pourquoi je l’ai mise tout en haut.

Si maintenant vous faites F5 vous constaterez que vous revenez non pas vers l’url en localhost, mais:

https://webapplication-24.azurewebsites.net/

 

Une solution à ce problème est de compléter le fichier de configuration avec cette section:

<system.identityModel.services>
    <federationConfiguration>
        <wsFederation reply="https://localhost:44309/"  />
    </federationConfiguration>
</system.identityModel.services>

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