La fonction d'adhésion ASP.NET réduit la quantité de code que vous devez écrire pour authentifier les utilisateurs et stocker leurs informations d'identification. Pour citer MSDN:
"L'appartenance ASP.NET vous donne un moyen intégré de valider et de stocker des informations d'identification de l'utilisateur.
Le fournisseur d'adhésion doit être spécifié dans le fichier de configuration web.config. Vous pouvez utiliser votre propre fournisseur personnalisé ou l'un des fournisseurs par défaut qui expédie avec le Framework .NET, tel que le fournisseur SQLMembershipprovider.
Toutes les données liées à l'utilisateur sont stockées dans un ensemble de tableaux utilisés par le système d'adhésion ASP.NET. Dans la plupart des cas, vous utiliserez un ensemble de tableaux par application Web. Cependant, vous pouvez également réutiliser le même ensemble pour stocker les informations d'identification de l'utilisateur de plusieurs applications Web. Cela vous permet efficacement de créer une application Web qui agit comme un portail vous permettant de vous connecter à l'une de ces applications "virtuelles".
Cependant, ce n'est pas possible hors de la boîte. Vous avez du travail devant vous, avant de pouvoir prendre en charge ces applications dynamiques.
Commençons ...
Commençons par examiner l'entrée Web.config suivante:
Listing 1 - Web.config ASP.NET Configuration de l'adhésion
< membership defaultProvider = " SqlProvider " >
< providers >
< clear />
< add name = " SqlProvider "
type = " System.Web.Security.SqlMembershipProvider "
connectionStringName = " YourConnectionStringName "
applicationName = " MyApplication "
... />
</ providers >
</ membership >Ces paramètres configurent votre application Web pour utiliser le SQLMembershipprovider pour gérer vos informations d'identification utilisateur. Toutes les données liées à vos utilisateurs sont stockées dans les tables d'adhésion ASP.NET par défaut.
Remarque : Cet article n'est pas une introduction à l'appartenance ASP.NET, vous devriez le connaître. Utilisez l'outil d'enregistrement ASP.NET SQL Server (ASPNET_REGSQL.EXE) pour configurer votre base de données.
Comme mentionné précédemment, vous pouvez stocker les informations d'identification de l'utilisateur de plusieurs applications Web dans le même ensemble de tables. Chaque application Web sépare ses données utilisateur en les partitionnant, dans ce que j'appelle, un contexte d'application. Ce contexte d'application est défini par la propriété de nom d'application du fournisseur d'adhésion. Comme vous pouvez le voir dans la liste 1, le nom de l'application est "MyApplication".
Le SQLMembershipprovider utilise ce paramètre pour déterminer dans quel contexte il doit fonctionner, toutes les données utilisateur liées à ce nom d'application seront accessibles par la bibliothèque d'adhésion ASP.NET et les contrôles de connexion.
Malheureusement, ce paramètre est défini statiquement dans le web.config. Vous ne pouvez pas facilement le changer pendant l'exécution. Si vous souhaitez prendre en charge les applications dynamiques, vous avez besoin d'un moyen de contrôler la valeur de la propriété Application Name du fournisseur. La solution réside dans la création de votre propre fournisseur d'adhésion ASP.NET.
Le SQLMembershipprovider récupère la valeur de sa propriété ApplicationName à partir des paramètres de configuration contenus dans le fichier web.config. Nous voulons modifier la valeur que le Getter de cette propriété renvoie.
Lors de la connexion à l'utilisateur, il faut clairement clairement ses intentions, en d'autres termes, il doit spécifier les applications virtuelles auxquelles il souhaite accéder. À cette fin, je nécessite que l'utilisateur spécifie non seulement son nom d'utilisateur et son mot de passe, mais aussi l'application virtuelle auquel il souhaite accéder. Du point de vue de l'utilisateur, j'appelle cette application virtuelle, le domaine.
Par exemple, supposons que vous ayez établi une base de données SQL Server appelée ASPNetMembership qui contient les tables d'adhésion ASP.NET. Cette base de données contient les applications virtuelles suivantes définies dans le tableau ASPNET_Applications:
Chaque application virtuelle contient un utilisateur avec le nom d'utilisateur "CGEERS". Maintenant, si je veux me connecter à l'application Northwind, je dois entrer dans mon nom d'utilisateur en tant que "Northwind cgeers". Pour l'application AdventureWorks, ce serait "Adventureworks cGeers".
La partie précédant le nom d'utilisateur est le nom de l'application ou en ce qui concerne l'utilisateur, c'est le domaine qu'il doit entrer afin de spécifier l'application virtuelle à laquelle il souhaite accéder. Le domaine et le nom d'utilisateur sont séparés par une barre oblique inverse.
Lorsque l'utilisateur se connecte à l'aide du contrôle de connexion ASP.NET, nous devons extraire le domaine qu'il a entré et stocker dans un emplacement auquel notre fournisseur d'adhésion personnalisé peut accéder. Cependant, nous devons tenir compte du fait qu'ASP.NET fonctionne dans un environnement multithread. Chaque demande reçue par ASP.NET est gérée par un thread séparé. Nous ne pouvons pas stocker le domaine dans n'importe quel endroit, autrement, d'autres demandes entrantes pourraient l'écraser. Il doit être lié à une seule demande.
L'endroit idéal pour stocker des informations contextuelles liées à une demande individuelle est le contexte HTTP actuel. Ces informations contextuelles sont encapsulées par la classe HTTPContext.
Démarrez Visual Studio et créez une nouvelle solution vierge appelée "ASPNetDynamicapplications". Ajoutez ensuite un nouveau projet de bibliothèque de classe à la solution nommée "cgeers.web.security". Ajoutez des références à System.Configuration et System.Web Assemblages. Notre fournisseur personnalisé descendra à partir du SQLMembershipprovider par défaut par défaut, ces références sont donc nécessaires.
Figure 1 - Solution Visual Studio

Renommez le fichier Class1.cs généré automatiquement vers DynamicApplicationsSQLMembershipprovider.cs et ajoutez le code indiqué dans la liste 2.
Listing 2 - DynamicApplicationsSqlMembershipprovider
public class DynamicApplicationsSqlMembershipProvider : SqlMembershipProvider
{
#region Fields
private const string ApplicationNameSetting = "ApplicationName" ;
#endregion
public override string ApplicationName
{
get
{
HttpContext context = HttpContext . Current ;
if ( context == null )
{
throw new InvalidOperationException ( "Http context cannot be null." ) ;
}
string applicationName = String . Empty ;
if ( context . Items . Contains ( ApplicationNameSetting ) )
{
if ( ! String . IsNullOrEmpty ( ( string ) context . Items [ ApplicationNameSetting ] ) )
{
applicationName = ( string ) context . Items [ ApplicationNameSetting ] ;
}
}
return applicationName ;
}
set
{
base . ApplicationName = value ;
}
}
}Comme vous pouvez le voir, notre fournisseur d'adhésion personnalisée descend à partir de SQLMembershipprovider par défaut et remplace la propriété ApplicationName. Nous ne sommes pas préoccupés par le setter, seulement par le Getter. Lorsque le fournisseur lit la propriété ApplicationName, nous obtenons une poignée au contexte HTTP actuel en appelant la propriété actuelle statique de la classe HTTPContext. L'objet HttpContext obtenu a une propriété de collecte de clé / valeur appelée éléments. Cette collection stocke le nom de l'application dans une entrée identifiée par la clé "ApplicationName". Le nom de cette clé est quelque chose que vous devez déterminer au moment de la conception.
Désormais, chaque fois que notre fournisseur d'adhésion personnalisé doit déterminer le nom de l'application, il appelle la propriété ApplicationName qui récupère la valeur du contexte HTTP actuel. Cela fonctionne dans l'environnement multithread d'ASP.NET car chaque demande est liée à son propre contexte HTTP.
Maintenant que nous avons un fournisseur d'adhésion personnalisé qui récupère la valeur de sa propriété d'application Name à partir du contexte HTTP Currect, nous devons toujours trouver un moyen de stocker le nom de l'application dans le contexte HTTP.
La première fois qu'un utilisateur spécifie l'application ou le domaine virtuel auxquels il souhaite accéder, c'est quand il se connecte. Comme mentionné précédemment, l'utilisateur doit entrer son nom d'utilisateur dans le format <domain><username> . Nous devons créer notre propre contrôle de connexion qui descend à partir du contrôle de connexion ASP.NET. Lors de l'authentification de l'utilisateur, nous devons extraire le domaine entré et l'enregistrer dans le contexte HTTP actuel.
Ajoutez un nouveau projet en utilisant le modèle de bibliothèque de classe à votre solution appelée "cgeers.web.ui.webControls". Ajoutez les références suivantes au projet:
Supprimez ensuite le fichier Class1.cs généré automatiquement et ajoutez une nouvelle classe appelée DynamicApplicationsLogin. Étant donné que le code de cette classe est assez long, j'ai choisi de le diviser en plusieurs listes. Après chaque liste, une brève explication du code est ajoutée.
Listing 3 - DynamicApplicationsLogin Control Propriétés privées
public class DynamicApplicationsLogin : Login
{
#region Fields
private string _fullUserName ;
#endregion
#region Properties
private string ApplicationName
{
get
{
string [ ] data = base . UserName . Split ( @"" . ToCharArray ( ) , 2 ) ;
string applicationName = ( data . Length == 2 ) ? data [ 0 ] : String . Empty ;
return applicationName ;
}
}
private string BaseUserName
{
get
{
string [ ] data = base . UserName . Split ( @"" . ToCharArray ( ) , 2 ) ;
string userName = ( data . Length == 2 ) ? data [ 1 ] : base . UserName ;
return userName ;
}
}
#endregion
// ...
}Comme vous pouvez le voir, le contrôle DynamicApplicationsLogin descend à partir du contrôle de connexion ASP.NET standard et un champ appelé _fullusername et deux propriétés privées ApplicationName et BaseUsername sont ajoutées.
Étant donné que l'utilisateur entre dans le domaine et le nom d'utilisateur dans le même contrôle de zone de texte, nous devons diviser ces pièces. Comme vous pouvez le deviner, la propriété ApplicationName extrait le domaine et le nom de base de base renvoie le nom d'utilisateur. Par exemple, si l'utilisateur entre dans Northwind cGeers, la propriété ApplicationName retournerait "Northwind" et la propriété BaseUsername renverrait "CGEERS".
Listing 4 - DynamicApplicationsLogin Control On Authhenticiate Method
protected override void OnAuthenticate ( AuthenticateEventArgs e )
{
HttpContext context = HttpContext . Current ;
if ( context == null )
{
throw new InvalidOperationException ( "Http context cannot be null." ) ;
}
MembershipProvider provider = Membership . Provider ;
if ( provider == null )
{
throw new InvalidOperationException ( "MembershipProvider cannot be null." ) ;
}
provider = provider as DynamicApplicationsSqlMembershipProvider ;
if ( provider == null )
{
throw new InvalidOperationException (
"The specified MembershipProvider must be of type DynamicApplicationsSqlMembershipProvider." ) ;
}
// Store the application name in the current Http context's items collections
context . Items [ "ApplicationName" ] = ApplicationName ;
// Validate the user
_fullUserName = UserName ;
UserName = BaseUserName ;
base . OnAuthenticate ( e ) ;
}Ensuite, vous devez remplacer la méthode OnAuthenticiate du contrôle de connexion pour vous assurer que l'utilisateur est validé dans le contexte d'application correct (application virtuelle).
Tout d'abord, cette méthode révèle une référence au contexte HTTP actuel, puis il vérifie si le fournisseur d'adhésion chargée est en effet notre DynamicApplications personnalisésSqlMembershipprovider. Ensuite, le domaine ou le nom d'application entré est stocké dans la collection d'éléments du contexte HTTP actuel afin que notre fournisseur d'adhésion puisse récupérer la valeur correcte pour sa propriété ApplicationName.
Enfin, la valeur de la propriété du nom d'utilisateur est définie pour ne contenir que le nom d'utilisateur en y attribuant la propriété BaseUsername. Le champ privé _fullusername stocke temporairement la valeur que l'utilisateur a saisi (nom d'utilisateur de domaine). Vous verrez comment ce champ est utilisé plus tard.
Une fois que le nom de l'application a été stocké dans le contexte HTTP et que la propriété du nom d'utilisateur ne contient que le nom d'utilisateur que l'implémentation de base est appelée, cela entraîne la validation du nom d'utilisateur à l'intérieur du contexte d'application correct.
Listing 5 -DynamicapplicationsLogin Control OnLoginerror Méthode
protected override void OnLoginError ( EventArgs e )
{
UserName = _fullUserName ;
base . OnLoginError ( e ) ;
}Remplacez la méthode OnLoginerror et avant d'appeler l'implémentation de base, affectez le champ _fulLatusername à la propriété Username. Lors de l'authentification de l'utilisateur (méthode OnAuthenticate), la propriété du nom d'utilisateur ne doit contenir que le nom d'utilisateur et non le domaine, mais lorsque l'authentification échoue, vous devez vous assurer que le texte que l'utilisateur est entré dans le contrôle de la zone de texte représentant le nom d'utilisateur est réinitialisé à la valeur que l'utilisateur initialement entré initialement. Autrement, cela pourrait être déroutant pour l'utilisateur si le domaine qu'il entrait disparaît.
Listing 6 - DynamicApplicationsLogin Control OnloggedIn Method
protected override void OnLoggedIn ( EventArgs e )
{
UserName = _fullUserName ;
HttpContext context = HttpContext . Current ;
if ( context == null )
{
throw new InvalidOperationException ( "Http context cannot be null." ) ;
}
string userName = BaseUserName ;
MembershipUser user = Membership . GetUser ( userName ) ;
if ( user != null )
{
string userData = String . Format ( "AN={0};" , ApplicationName ) ;
HttpCookie cookie = FormsAuthenticationHelper . StoreUserDataInAuthenticationCookie (
userName , userData , RememberMeSet
) ;
// Manually add the cookie to the Cookies collection
context . Response . Cookies . Add ( cookie ) ;
}
}Pour terminer le contrôle DynamicApplicationsLogin, vous devez remplacer la méthode OnloggedIn. Le nom de l'application est stocké dans la propriété UserData d'une FormsAuthenticationTicket. Ce billet d'authentification est utilisé par l'authentification des formulaires pour identifier un utilisateur authentifié. Ici, nous le stockons dans un cookie et l'ajoutons à la réponse du contexte HTTP actuel. Plus tard, vous verrez pourquoi cela est nécessaire.
Si vous jetez un coup d'œil à Listing 6, vous verrez que le cookie contenant le billet d'authentification des formulaires est créé par une classe d'assistance appelée FormsAuthenticationHelper. Il s'agit d'une classe d'assistance statique qui ne contient qu'une seule méthode, à savoir StoreUserDatainAuthenticationcookie.
Ajoutez une nouvelle classe appelée FormsAuthenticationHelper au projet CGEERS.Web.Security et ajoutez le code indiqué dans la liste 7.
Listing 7 - FormsAuthenticationHelper
public static class FormsAuthenticationHelper
{
public static HttpCookie StoreUserDataInAuthenticationCookie (
string userName , string userData , bool persistent )
{
if ( String . IsNullOrEmpty ( userName ) )
{
throw new InvalidOperationException ( "UserName cannot be null or empty." ) ;
}
if ( String . IsNullOrEmpty ( userData ) )
{
throw new InvalidOperationException ( "User data cannot be null or empty." ) ;
}
// Create the cookie that contains the forms authentication ticket
HttpCookie cookie = FormsAuthentication . GetAuthCookie ( userName , persistent ) ;
// Get the FormsAuthenticationTicket out of the encrypted cookie
FormsAuthenticationTicket ticket = FormsAuthentication . Decrypt ( cookie . Value ) ;
// Create a new FormsAuthenticationTicket that includes our custom user data
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket ( ticket . Version ,
ticket . Name ,
ticket . IssueDate ,
ticket . Expiration ,
persistent ,
userData ) ;
// Update the cookie's value to use the encrypted version of our new ticket
cookie . Value = FormsAuthentication . Encrypt ( newTicket ) ;
// Return the cookie
return cookie ;
}
}La méthode StoreUserDatainAuthenticationCookie (...) récupère le cookie pour l'utilisateur spécifié (paramètre de nom d'utilisateur) qui contient le billet d'authentification des formulaires. Ensuite, le cookie est décrypté afin d'accéder à l'objet FormsAuthenticationTicket. Ensuite, un nouveau formsAuthenticationTicket est créé en fonction de l'ancien billet et la valeur contenue dans le paramètre UserData est stockée dans ce billet. Dans la dernière étape, le nouvel objet FormsAuthenticationTicket est stocké dans un cookie crypté.
Remarque : Les magasins de contrôle DynamicApplicationsLogin renvoient ce cookie à l'utilisateur, donc le client doit prendre en charge les cookies!
Récapitulons ce que nous avons jusqu'à présent.
Nous avons donc notre fournisseur d'adhésion personnalisé qui est capable, par demande, de déterminer le contexte d'application dans lequel fonctionner et nous avons un contrôle de connexion personnalisé qui identifie ce contexte en exigeant que les utilisateurs précèdent leur nom d'utilisateur avec un domaine (= nom d'application).
Cela fonctionne assez bien si votre application Web ne se compose qu'une page de connexion. N'oubliez pas que le fournisseur d'adhésion personnalisé détermine le contexte de l'application en lisant le nom de l'application stocké dans le contexte HTTP actuel. Avec chaque demande que vous faites, un nouveau contexte HTTP est créé. Lors de la connexion du nom de l'application est explicitement stocké dans le contexte HTTP. Cependant, pour toute demande ultérieure, ce n'est pas le cas. D'une manière ou d'une autre, nous devons nous assurer que le contexte HTTP est correctement initialisé avec le nom de l'application avec chaque demande après que l'utilisateur s'est connecté.
Comme mentionné précédemment, le contrôle DynamicApplicationLogin envoie un cookie chiffré à l'utilisateur après avoir été connecté avec succès. Ce cookie contient le nom de l'application et est envoyé avec chaque demande suivante. Voila, maintenant tout ce dont nous avons besoin est un moyen d'insérer une logique dans le pipeline de demande ASP.NET, afin de lire le contenu de ce cookie et de stocker le nom d'application récupéré dans le contexte HTTP.
Un module HTTP est parfait pour cette situation. Un module HTTP est appelé à chaque demande et s'exécute avant et après une demande traitée.
Ajoutez une nouvelle classe appelée DynamicApplicationsModule au projet CGEERS.Web.Security. Cette classe doit implémenter l'interface Ihttpmodule. Le code de ce module HTTP s'affiche dans la liste 8.
Listing 8 - DynamicApplicationsModule
public class DynamicApplicationsModule : IHttpModule
{
#region Fields
private const string ApplicationNameSetting = "ApplicationName" ;
#endregion
#region IHttpModule Members
public void Dispose ( )
{ }
public void Init ( HttpApplication context )
{
context . AuthenticateRequest += DetermineApplicationName ;
}
#endregion
private static void DetermineApplicationName ( object sender , EventArgs e )
{
// Access the current Http application.
HttpApplication application = sender as HttpApplication ;
if ( application == null )
{
throw new InvalidOperationException ( "Http application cannot be null." ) ;
}
// Get the HttpContext for the current request.
HttpContext context = application . Context ;
if ( context == null )
{
throw new InvalidOperationException ( "Http context cannot be null." ) ;
}
// Read the application name stored in the FormsAuthenticationTicket
string applicationName = String . Empty ;
if ( context . Request . IsAuthenticated )
{
FormsIdentity identity = context . User . Identity as FormsIdentity ;
if ( identity != null )
{
FormsAuthenticationTicket ticket = identity . Ticket ;
if ( ticket != null )
{
applicationName = ticket . GetApplicationName ( ) ;
}
}
}
// Store the application name in the Items collection of the per-request http context.
// Storing it in the session state is not an option as the session is not available at this
// time. It is only available when the Http application triggers the AcquireRequestState event.
context . Items [ ApplicationNameSetting ] = applicationName ;
}
}La méthode init (...) initialise un module HTTP et la prépare à gérer les demandes. Ici, l'événement AuthenticateRequest du HTTPAPPLICATION est accroché au gestionnaire d'événements de détermination.
Le gestionnaire d'événements de détermination de laapplication (...) vérifie s'il s'agit d'une demande authentifiée et si oui, récupère le billet FormsAuthentication envoyé par le client.
Ce billet identifie le contexte d'application dans lequel fonctionner. Le nom de l'application est extrait du billet à l'aide de la méthode FormsAuthenticationTicket GetApplicationName (). Il s'agit d'une méthode d'extension, je vais y remédier dans la section suivante.
Enfin, après avoir extrait le nom de l'application du billet, il est stocké dans le contexte HTTP afin que notre fournisseur d'adhésion personnalisé puisse le lire.
Ajoutez une nouvelle classe appelée FormsAuthenticationTickEtextensions au projet CGEERS.Web.Security et ajoutez le code indiqué dans la liste 9.
Listing 9 - FormsAuthenticationTickEtextensions
internal static class FormsAuthenticationTicketExtensions
{
public static string GetApplicationName ( this FormsAuthenticationTicket ticket )
{
// Check if the application name (AN=) is stored in the ticket's userdata.
string applicationName = String . Empty ;
List < string > settings = new List < string > ( ticket . UserData . Split ( ';' ) ) ;
foreach ( string s in settings )
{
string setting = s . Trim ( ) ;
if ( setting . StartsWith ( "AN=" ) )
{
int startIndex = setting . IndexOf ( "AN=" ) + 3 ;
applicationName = setting . Substring ( startIndex ) ;
break ;
}
}
return applicationName ;
}
}Comme vous pouvez le voir dans Listing 6, le contrôle DynamicApplicationLogin enregistre le nom de l'application dans la propriété UserData de FormsAuthenticationTicket en le précédant avec le préfixe "an =". Ainsi, cette méthode d'extension doit prendre cela en compte lors de la récupération du nom de l'application à partir d'un FormsAuthenticationTicket.
Remarque : N'hésitez pas à améliorer la façon dont le nom de l'application est stocké dans le billet, mais n'oubliez pas d'implémenter le même système pour le contrôle DynamicApplicationsLogin et cette méthode d'extension.
Semblable au contrôle DynamicApplicationsLogin, j'ai créé des contrôles qui descendent à partir des contrôles ASP.NET PasswordRecovery et ChangePassword. Si vous souhaitez qu'un utilisateur puisse récupérer son mot de passe et / ou le modifier, vous devez utiliser ces contrôles. Ils s'assurent que tout est exécuté dans le contexte d'application correct.
L'implémentation est très similaire à celle du contrôle DynamicApplicationsLogin, donc je ne répertorierai pas le code de ces contrôles ici. Si vous souhaitez consulter le code source de ces contrôles, téléchargez le code source accompagnant cet article. Vous pouvez trouver ces contrôles dans le projet cgeers.web.ui.webControls.
Le code source accompagnant cet article contient également un projet d'application Web de démonstration qui démontre le DynamicApplicationsSQLMembershipprovider, les nouveaux contrôles de connexion, notre module HTTP personnalisé ... et ainsi de suite.
Figure 2 - Solution Visual Studio

Afin d'exécuter cette application de démonstration, veuillez suivre ces étapes:
Après avoir suivi ces étapes, vous devriez être prêt à exécuter l'application Web de démonstration. Vous avez créé une base de données qui contient deux applications et un utilisateur pour chaque application.
Lorsque vous démarrez l'application Web, vous pouvez vous connecter à chaque application en spécifiant le nom de l'application (domaine) suivi d'une barre oblique inverse et du nom d'utilisateur. Bien sûr, le mot de passe de l'utilisateur est également requis.
Les commandes de connexion que nous avons créées prennent soin du reste et assurez-vous que vous opérez dans le contexte d'application correct. Tout appel ultérieur avec la bibliothèque d'adhésion ASP.NET déclenchera le fournisseur d'adhésion personnalisé pour renvoyer le nom de l'application correct, s'assurant ainsi que ces appels fonctionnent dans le contexte de l'application correcte.
Remarque : Le fichier Web.config de l'application Web de démonstration contient des commentaires qui spécifient tout ce que vous devez faire afin de configurer correctement l'application. Assurez-vous de le vérifier.
Cet article vous a montré comment peut-être utiliser le système d'adhésion ASP.NET pour créer une application de portail qui permet aux utilisateurs de se connecter à l'une des nombreuses applications virtuelles.
La première clé pour réaliser cela consiste à créer un fournisseur d'adhésion personnalisé qui s'assure que vous opérez dans le contexte d'application correct en récupérant la valeur de la propriété ApplicationName à partir d'un emplacement de stockage lié à une demande individuelle.
En créant un contrôle de connexion personnalisé qui descend à partir du contrôle de connexion ASP.NET standard, nous pouvons déterminer quelle application l'utilisateur souhaite accéder.
En encapsulant ces informations dans un cookie crypté, nous sommes en mesure d'identifier automatiquement l'application à laquelle l'utilisateur souhaite accéder à chacune de ses demandes.