Apprendre à créer des pages Web Dynamiques avec ASP.NET
...
Redirection automatique vers une page d’authentification
Une des possibilités d’ASP.NET en matière de sécurité est l’implémentation d’un mécanisme d’authentification automatique qui redirige les utilisateurs non authentifiés vers une page demandant la saisie d’un identifiant et d’un mot de passe (voir figure 9-1).
Pour mettre en œuvre ce mécanisme d’authentification, qui repose sur l’utilisa-tion d’un cookie :
1 Réalisez une page nommée, par exemple, login.aspx, contenant deux zones d’éditions qui permettent respectivement la saisie d’un identifiant et d’un mot de passe et un bouton qui effectue l’établissement de la connexion, auquel on associera un gestionnaire d’événement décrit plus loin.
2 Modifiez le fichier web.config de l’application en lui rajoutant une section <authentification> qui spécifie le type d’authentification (Forms pour for¬mulaire Web), la page utilisée pour l’authentification (loginUrl), la durée de vie du cookie associé à la session (en minutes) et la liste des identifiants et mots de passe autorisés à accéder à l’application..
<authentication mode="Forms">
<forms name=".sds" loginUrl="login.aspx"
protection="All" timeout="30" path="/">
<credentials passwordFormat="Clear" >
<user name="administrateur" password="password1"/>
<user name="marketing" password password2"/>
<user name="logistique" password=" password3"/>
</credentials>
</forms>
</authentication>
<authorization> <deny users="?"/> </authorization> 3 Cette section spécifie qu’il faut rejeter toutes les requêtes des utilisateurs non authentifiés.
3 Associez un gestionnaire à l’événement Click du bouton de connexion, qui réalise la validation des informations saisies grâce à la méthode Authenticate de la classe FormsAuthentication et redirige, en cas de succès, l’utilisateur vers la page demandée.
Ficher login.aspx (Version C#)
void OnClick_DoConnect(Object sender, EventArgs e)
{
if (FormsAuthentication.Authenticate(UserID.Text,Password.Text))
{
FormsAuthentication.RedirectFromLoginPage(UserID.Text,false);
else
{
Message.Text = "Identification incorrecte. Merci de réessayer";
La version VB.NET de ce code est disponible en ligne à l’adresse Contrôle des autorisations en fonction de l’utilisateur
Une fois l’utilisateur authentifié, il est possible de gérer les autorisations accor-dées à l’utilisateur en fonction de son identifiant ou de son rôle, grâce aux infor¬mations fournies par l’objet Context.User, accessible au sein de l’application. On peut par exemple modifier le contrôle utilisateur Barre de navigation de manière à ce que:
Pour cela :
1 Ajoutez le texte « Utilisateur: » suivi d’un contrôle serveur de type Label nommé Utilisateur en bas à droite du contrôle Barre de navigation.
2 Ajoutez le code suivant à la fin du gestionnaire Page_Load du fichier NavBar.ascx implémenté au chapitre 3 :
Les fichiers de configuration ASP.NET
La configuration des applications ASP.NET s’effectue par l’intermédiaire d’une hiérarchie de fichiers XML portant l’extension .config (figure 9-2) :
Les mises à jour effectuées sur ces fichiers, lesquels présentent au pas¬sage l’avantage d’être faciles à lire et à éditer, sont prises en compte immédiatement sans nécessiter de redémarrage du serveur HTTP : les options de configuration sont conservées dans l’objet Cache d’ASP.NET, qui est automatiquement mis à jour lorsqu’une modification des fichiers de configuration est détectée; un nouveau domaine d’application (application domain) est alors automatiquement instancié par le CLR pour traiter les requêtes des nouveaux utilisateurs en appli¬quant les nouvelles options, tandis que l’ancien domaine est conservé tant qu’il y a des utilisateurs qui lui sont connectés.
web.config
Racine IIS
machine.config
Figure 9–2 Fichiers de configuration ASP.NET
Le redémarrage d’IIS n’est plus nécessaire
Les applications ASP étant basées sur la métabase IIS, la prise en compte d’un changement de configuration nécessitait un redémarrage d’IIS : le mécanisme des fichiers de configuration ASP.NET supprime cette contrainte.
Format d’un fichier .config (simplifié)
< ?xml version= "1.0" encoding="UTF-8" ?>
L’élément de plus haut niveau doit être de type <configuration>.
La section <system.web> contient les principales options relatives à la configuration de l’application (sécurité, internationalisation, ges¬tion des erreurs, etc.).
La section <appSettings> est généralement utilisée pour spécifier des paramètres relatifs à l’application que l’on souhaite pouvoir faci¬lement modifier (chaîne de connexion à la base de données, nom du serveur SMTP, etc.).
<configuration>
<system.web>
...
</system.web>
<appSettings> ...
</appSettings> </configuration>
Fichier NavBar.ascx (Gestionnaire Page_Load / Version C#)
...
string userName = Context.User.Identity.Name; Utilisateur.Text = userName;
if (userName == "marketing")
{
if ((SelectedIndex ==1) || (SelectedIndex == 2))
Response.Redirect("login.aspx");
Rubrique2.Visible = false;
Rubrique3.Visible = false;
}
if (userName == "logistique") {
if ((SelectedIndex ==3))
Response.Redirect("login.aspx");
Rubrique4.Visible = false;
}
Le résultat de l’exécution pour l’utilisateur « marketing » est présenté figure 9-3.
Figure 9–3 Gestion sélective des autorisations
Sécurisation d’un service Web
À l’image des applications Web s’exécutant dans un navigateur, les services Web nécessitent généralement un mécanisme de sécurisation: par exemple, il paraît indispensable de contrôler l’identité des programmes qui réalisent une mise à jour des stocks par l’intermédiaire du service développé dans le chapitre précédent.
Cette authentification peut être réalisée grâce à la transmission des informations relatives à l’utilisateur (identifiant et mot de passe) dans l’en-tête des messages SOAP, comme l’illustre la figure 9-4.
La sécurisation d’un service Web se déroulera en trois étapes :
Voici par exemple le code du service Web ServiceStocks, développé au chapitre 8, après intégration du mécanisme de sécurisation:
ServicesStocks.asmx (Version VB.NET – Avec sécurisation)
Public class ServiceStocks : Inherits WebService
Public Class AuthHeader : Inherits SoapHeader
Public Username As String Public Password As String End Class
Public sHeader As AuthHeader
<WebMethod(EnableSession:=True),SoapHeader("sHeader")> Public Function AjouterMouvementStock(...)
If (sHeader Is Nothing)
Return "Erreur : absence d'informations d'authentification" End If
If (sHeader.Username <> "<YourID>") Or
X (sHeader.Password <> "<YourPwd")
Return "Erreur : authentification incorrecte"
End If
...
End Function
Du côté client, il suffit ensuite de générer le proxy correspondant (grâce à l’utili¬taire WSDL, voir chapitre précédent) et d’utiliser la propriété AuthHeaderValue (générée du fait de la présence de l’attribut SoapHeader) pour spécifier les infor¬mations d’authentification à transmettre au service:
Dim proxy As ServiceStocks = new ServiceStocks()
Dim authInfo As AuthHeader = new AuthHeader
authInfo.Username = "login" authInfo.Password = "password" proxy.AuthHeaderValue = authInfo proxy.AjouterMouvementStock(...)
Débogage et gestion des erreurs
La gestion des erreurs constituant un élément très important de la qualité d’une application, ASP.NET met à la disposition du développeur un certain nombre de techniques qui permettent l’analyse, le débogage ainsi que le traitement spé¬cifique des exceptions:
Analyser l’exécution d’une application
Deux techniques sont possibles pour tracer l’exécution d’une application : l’utili¬sation de l’option Trace, très facile à mettre en œuvre mais limitée à l’affichage de messages décrivant les différentes étapes de l’exécution d’une page, et le recours au débogueur .NET, qui permet d’atteindre un niveau d’analyse avancé.
Accéder rapidement au déroulement détaillé avec l’option Trace
L’option Trace de la directive Page est le moyen le plus simple d’avoir une vision globale de l’exécution d’une page : lorsqu’elle est activée, un résumé complet des éléments liés à la requête (heure, identifiant de session, contenu de l’objet Session, encodage de la réponse...) et à l’exécution de la page (heures de début et de fin de l’exécution des principaux événements prédéfinis) est ajouté à la suite du contenu HTML produit.
En outre, l’utilisateur a la possibilité de rajouter des messages de trace au sein du code grâce aux méthodes Write et Warn de la propriété Trace de la classe Page, qui seront automatiquement ignorées si l’option Trace est désactivée.
Voici, par exemple, la marche à suivre pour tracer l’exécution de la page d’accueil de notre étude de cas, en étudiant en particulier le temps de réponse du service Web associé au contrôle Meteo développé dans le chapitre précédent:
1 Activez l’option Trace pour la page default.aspx :
<%@ Page Language="<YourLanguage>" Trace="True" %>
2 Insérez des instructions de trace (Trace.Write) pour encadrer les appels au service Web.
Fichier Meteo.ascx (Version C#)
Trace.Write("Contrôle météo","Avant GetWeatherInfos (Paris)");
infos = GetWeatherInfos("LFPO");
Trace.Write("Contrôle météo","Après GetWeatherInfos Paris");
...
Trace.Write("Contrôle météo","Avant GetWeatherInfos (Marseille)");
infos = GetWeatherInfos("LFML");
Trace.Write("Contrôle météo","Après GetWeatherInfos (Marseille)");
Si on exécute la page, on constate qu’elle est suivie d’un rapport complet des informations de trace, qui inclut les instructions spécifiées par l’intermédiaire de Trace.Write (figure 9-5).
Figure 9–5 Exécution d’une page avec activation de l’option Trace
Si le mécanisme de trace permet d’obtenir rapidement un grand nombre d’infor¬mations pertinentes, il ne permet pas de détailler pas à pas l’exécution d’une page : il faut pour cela recourir au débogueur.
Examiner en détail le déroulement de l’exécution avec le débogueur .NET
Le kit de développement .NET est fourni avec un débogueur gratuit et très puissant, qui possède pratiquement toutes les fonctionnalités du débogueur de Visual Studio.NET (à l’exclusion du Edit and Continue et du débogage d’appli-cations distantes) :
1 Démarrez le débogueur (voir remarque).
2 Ouvrez le fichier source correspondant à la page que vous souhaitez déboguer.
3 Choisissez Debug Processes... dans le menu Tools.
4 Sélectionnez le processus aspnet_wp.exe et cliquez sur Attacher (voir figure 9-6).
5 Positionnez au moins un point d’arrêt dans le code de la page (par exemple, dans le gestionnaire Page_Init ou Page_Load) afin de basculer dans le débo¬gueur lors de l’exécution de la page.
6 Enfin, exécutez la page dans un navigateur: le point d’arrêt s’active dans le débogueur (voir figure 9-7).
Optimiser les performances de l’application grâce au maintien en cache
ASP.NET offre la possibilité de configurer le maintien en cache d’une page ou d’un con¬trôle utilisateur en fonction de paramètres divers: délai de conservation dans le cache fixé par l’utilisateur, variation en fonction du type de navigateur utilisé (une nouvelle ver¬sion de la page est produite pour chaque nou¬veau navigateur, mais la version en cache est utilisée pour plusieurs requêtes successives émanant d’un même navigateur), de la pré¬sence de certains paramètres dans la chaîne de requête ou dans l’en-tête HTTP de la requête.
L’intérêt principal de ce mécanisme est d’opti¬miser les performances de l’application : par exemple, minimiser le temps d’affichage de la page d’accueil de notre intranet, qui contient le contrôle Meteo, lequel interroge le service GlobalWeather. En effet, le temps de réponse du service étant de plusieurs secon¬des et les données fournies n’étant mises à jour que toutes les deux heures, il est perti¬nent de maintenir en cache le résultat de l’exécution du contrôle.
Pour cela, il suffit d’ajouter la directive sui¬vante en haut de la page Meteo.ascx : où Duration spécifie le nombre de secondes pendant lequel il faut maintenir la version en cache (ici : deux heures).
D’autres options sont disponibles comme VaryByCustom, VaryByHeader, VaryByParam, qui permettent de paramétrer plus précisé¬ment la mise à jour du cache en fonction du navigateur, de l’en-tête HTTP ou de la chaîne de requête, comme précisé précédemment.
Si le débogueur permet d’accélérer la mise au point d’une application, il ne permet pas d’éviter les défaillances d’éléments externes qui conduisent à la géné¬ration d’exceptions, dont le traitement est l’objet de la section suivante.
Tableau 9–1 Principales commandes utilisables dans le débogueur
Touche de raccourci F5 Action
Aller jusqu’au point d’arrêt suivant
F9 Créer ou supprimer un point d’arrêt
F10 Exécuter pas à pas sans entrer dans les fonctions appelées
F11 Exécuter pas à pas en entrant dans les fonctions appelées
Shift + F11 Sortir d’une fonction appélée
La gestion des exceptions
Tous les langages .NET permettent d’utiliser le mécanisme de gestion des exceptions, bien connu des programmeurs C++ et Java, afin de réaliser un traite¬ment de tous les cas d’erreurs, notamment ceux qui émanent d’éléments externes à l’application (fichiers introuvables, serveurs de données inaccessibles, services Web indisponibles...).
Le principe consiste à encadrer le code susceptible de générer des exceptions entre deux instructions Try et Catch, comme le montre l’exemple qui suit, ins-piré de la fonction ChargerListeFamilles développée au chapitre 4.
Stocks.aspx – (version VB.NET avec gestion des exceptions)
Sub ChargerListeFamilles()
Dim myConnection As SqlConnection Dim myCommand As SqlCommand
Dim myReader As SqlDataReader Dim SQL As String
Try
myConnection = CType(Session("myConnection"),SqlConnection)
SQL = "SELECT * FROM FamilleProduit" myCommand = new SqlCommand(SQL,myConnection)
myReader = myCommand.ExecuteReader()
ListeFamilles.DataSource = myReader
ListeFamilles.DataValueField = "ID_FamilleProduit" ListeFamilles.DataTextField = "NomFamille" ListeFamilles.DataBind()
myReader.Close()
Catch e As Exception
Response.Redirect("Erreur.aspx?message="+e.Message) End Try
End Sub
Notons que le développeur a également la possibilité de générer des exceptions à l’aide du mot-clé Throw, voire de définir ses propres types d’exceptions, dérivés de la classe ApplicationException définie dans l’espace de nommage System.
Tel qu’il a été décrit, ce mécanisme présente l’inconvénient de nécessiter l’implémentation d’un bloc Try/Catch dans toutes les fonctions susceptibles de générer une exception. Heureusement, nous allons voir qu’ASP.NET dispose également de techniques qui permettent de traiter de manière générique toutes les erreurs pouvant survenir dans une application.
Gestion spécifique des erreurs
Parmi les types d’erreurs susceptibles de survenir lors de l’exécution d’une appli¬cation Web, on peut distinguer:
ASP.NET propose des solutions techniques pour gérer ces différents cas d’erreurs : il est possible de spécifier une page d’erreur personnalisée associée à un type d’erreur HTTP ainsi que d’intercepter l’ensemble des erreurs applica-tives au sein d’un gestionnaire d’événement Application_Error, afin de leur appliquer un traitement spécifique.
Spécifier une page d’erreur personnalisée
Pour spécifier une page d’erreur par défaut qui permette de notifier les dysfonc-tionnements de manière conviviale à l’utilisateur, il suffit d’insérer une section <customErrors> dans le fichier de configuration de l’application, en spécifiant:
Fichier web.config
<system.web>
<customErrors defaultRedirect="Erreur.aspx" mode="On"> <error statusCode="404" redirect="Erreur404.aspx"/> </customErrors>
</system.web>
Intercepter l’ensemble des erreurs survenant dans une application
Le gestionnaire Application_Error défini dans le fichier global.asax permet d’intercepter l’ensemble des erreurs susceptibles de survenir lors de l’exécution d’une application.
Il est possible, par exemple, d’envoyer un message contenant la description de l’erreur à l’administrateur, tout en redirigeant l’utilisateur vers une page convi¬viale, comme le montre l’exemple de code proposé.
Fichier global.asax (version C#)
void Application_Error(Object sender, EventArgs E) {
MailMessage mail = new MailMessage();
mail.From = ""; mail.To = "<VotreAdresse>";
mail.Subject = "Une erreur ASP.NET s'est produite"; mail.Body = Server.GetLastError().ToString(); mail.BodyFormat = MailFormat.Text;
SmtpMail.SmtpServer = "<VotreServeurSMTP>"; SmtpMail.Send(mail);
Server.ClearError();
Response.Redirect("Erreur.aspx");
}
Après ce tour d’horizon des possibilités d’ASP.NET en matière de gestion d’erreurs, nous allons maintenant détailler le déploiement d’une application vers un serveur de production.
Déploiement d’une application ASP.NET
En pratique, une application ASP.NET est composée de deux types d’éléments :
Le mécanisme le plus simple pour déployer une application ASP.NET consiste à effectuer une simple copie des fichiers vers le répertoire de l’application sur la machine cible (les assemblages doivent être copiés dans le sous-répertoire bin).
Cette technique, présentée figure 9-9, présente deux avantages majeurs:
Figure 9–9 Déploiement d’une application ASP.NET
Dans certains cas, il peut être utile de partager des assemblages fréquemment utilisés entre toutes les applications d’une machine donnée (afin d’éviter d’avoir à les déployer dans le répertoire bin de chaque application) : c’est le rôle du Global Assembly Cache (GAC), dont nous allons maintenant décrire le fonction¬nement.
Déployer un assemblage dans le Global Assembly Cache
Avant de pouvoir être installé dans le Global Assembly Cache, un assemblage doit être signé numériquement à l’aide d’un mécanisme clé publique/clé privée, ceci pour deux raisons:
sn –k <NomFichier>
où <NomFichier> désigne le nom du fichier de clés à générer (auquel on donne généralement l’extension .snk).
sn.exe
Figure 9–10 Une des techniques possibles pour la signature d’un assemblage
Une fois la paire de clés générée, deux techniques sont disponibles pour signer un assemblage:
<Assembly: AssemblyKeyFile("MyKeyPair.snk")> (Version VB.NET) [assembly: AssemblyKeyFile("MyKeyPair.snk")] (Version C#)
Une fois l’assemblage signé, il peut être installé dans le Global Assembly Cache à l’aide de l’utilitaire gacutil, dont la syntaxe d’utilisation est la suivante (voir figure 9-12) :
gacutil –i <NomAssemblage>
Figure 9–12 Installation d’un assemblage dans le Global Assembly Cache
Droits spécifiques nécessaires
Contrairement au déploiement d’assemblages pri¬vés (XCOPY), l’installation d’un nouvel assemblage partagé dans le GAC nécessite d’avoir des droits spécifiques sur la machine cible (par exemple, accès en mode Terminal Server pour pouvoir exé¬cuter gacutil).
Localisation du Global Assembly Cache
Par défaut, le Global Assembly Cache est installé dans le répertoire \WINNT\assembly.
L’installation de l’assemblage peut être contrôlée grâce à l’utilitaire Microsoft .NET Framework Configuration, accessible via le dossier Outils d’administration du panneau de configuration, qui permet de visualiser l’ensemble des éléments présents dans le Global Assembly Cache (voir figure 9-13).
Figure 9–13 Visualisation du contenu du Global Assembly Cache
En résumé...
Dans ce dernier chapitre, nous avons passé en revue les principaux sujets relatifs à la sécurisation, la configuration, l’optimisation et la mise en production d’une application ASP.NET :
Apprendre à créer des pages Web Dynamiques avec ASP.NET
...
Redirection automatique vers une page d’authentification
Une des possibilités d’ASP.NET en matière de sécurité est l’implémentation d’un mécanisme d’authentification automatique qui redirige les utilisateurs non authentifiés vers une page demandant la saisie d’un identifiant et d’un mot de passe (voir figure 9-1).
Pour mettre en œuvre ce mécanisme d’authentification, qui repose sur l’utilisa-tion d’un cookie :
1 Réalisez une page nommée, par exemple, login.aspx, contenant deux zones d’éditions qui permettent respectivement la saisie d’un identifiant et d’un mot de passe et un bouton qui effectue l’établissement de la connexion, auquel on associera un gestionnaire d’événement décrit plus loin.
2 Modifiez le fichier web.config de l’application en lui rajoutant une section <authentification> qui spécifie le type d’authentification (Forms pour for¬mulaire Web), la page utilisée pour l’authentification (loginUrl), la durée de vie du cookie associé à la session (en minutes) et la liste des identifiants et mots de passe autorisés à accéder à l’application..
<authentication mode="Forms">
<forms name=".sds" loginUrl="login.aspx"
protection="All" timeout="30" path="/">
<credentials passwordFormat="Clear" >
<user name="administrateur" password="password1"/>
<user name="marketing" password password2"/>
<user name="logistique" password=" password3"/>
</credentials>
</forms>
</authentication>
<authorization> <deny users="?"/> </authorization> 3 Cette section spécifie qu’il faut rejeter toutes les requêtes des utilisateurs non authentifiés.
3 Associez un gestionnaire à l’événement Click du bouton de connexion, qui réalise la validation des informations saisies grâce à la méthode Authenticate de la classe FormsAuthentication et redirige, en cas de succès, l’utilisateur vers la page demandée.
Ficher login.aspx (Version C#)
void OnClick_DoConnect(Object sender, EventArgs e)
{
if (FormsAuthentication.Authenticate(UserID.Text,Password.Text))
{
FormsAuthentication.RedirectFromLoginPage(UserID.Text,false);
else
{
Message.Text = "Identification incorrecte. Merci de réessayer";
La version VB.NET de ce code est disponible en ligne à l’adresse Contrôle des autorisations en fonction de l’utilisateur
Une fois l’utilisateur authentifié, il est possible de gérer les autorisations accor-dées à l’utilisateur en fonction de son identifiant ou de son rôle, grâce aux infor¬mations fournies par l’objet Context.User, accessible au sein de l’application. On peut par exemple modifier le contrôle utilisateur Barre de navigation de manière à ce que:
Pour cela :
1 Ajoutez le texte « Utilisateur: » suivi d’un contrôle serveur de type Label nommé Utilisateur en bas à droite du contrôle Barre de navigation.
2 Ajoutez le code suivant à la fin du gestionnaire Page_Load du fichier NavBar.ascx implémenté au chapitre 3 :
Les fichiers de configuration ASP.NET
La configuration des applications ASP.NET s’effectue par l’intermédiaire d’une hiérarchie de fichiers XML portant l’extension .config (figure 9-2) :
Les mises à jour effectuées sur ces fichiers, lesquels présentent au pas¬sage l’avantage d’être faciles à lire et à éditer, sont prises en compte immédiatement sans nécessiter de redémarrage du serveur HTTP : les options de configuration sont conservées dans l’objet Cache d’ASP.NET, qui est automatiquement mis à jour lorsqu’une modification des fichiers de configuration est détectée; un nouveau domaine d’application (application domain) est alors automatiquement instancié par le CLR pour traiter les requêtes des nouveaux utilisateurs en appli¬quant les nouvelles options, tandis que l’ancien domaine est conservé tant qu’il y a des utilisateurs qui lui sont connectés.
web.config
Racine IIS
machine.config
Figure 9–2 Fichiers de configuration ASP.NET
Le redémarrage d’IIS n’est plus nécessaire
Les applications ASP étant basées sur la métabase IIS, la prise en compte d’un changement de configuration nécessitait un redémarrage d’IIS : le mécanisme des fichiers de configuration ASP.NET supprime cette contrainte.
Format d’un fichier .config (simplifié)
< ?xml version= "1.0" encoding="UTF-8" ?>
L’élément de plus haut niveau doit être de type <configuration>.
La section <system.web> contient les principales options relatives à la configuration de l’application (sécurité, internationalisation, ges¬tion des erreurs, etc.).
La section <appSettings> est généralement utilisée pour spécifier des paramètres relatifs à l’application que l’on souhaite pouvoir faci¬lement modifier (chaîne de connexion à la base de données, nom du serveur SMTP, etc.).
<configuration>
<system.web>
...
</system.web>
<appSettings> ...
</appSettings> </configuration>
Fichier NavBar.ascx (Gestionnaire Page_Load / Version C#)
...
string userName = Context.User.Identity.Name; Utilisateur.Text = userName;
if (userName == "marketing")
{
if ((SelectedIndex ==1) || (SelectedIndex == 2))
Response.Redirect("login.aspx");
Rubrique2.Visible = false;
Rubrique3.Visible = false;
}
if (userName == "logistique") {
if ((SelectedIndex ==3))
Response.Redirect("login.aspx");
Rubrique4.Visible = false;
}
Le résultat de l’exécution pour l’utilisateur « marketing » est présenté figure 9-3.
Figure 9–3 Gestion sélective des autorisations
Sécurisation d’un service Web
Cette authentification peut être réalisée grâce à la transmission des informations relatives à l’utilisateur (identifiant et mot de passe) dans l’en-tête des messages SOAP, comme l’illustre la figure 9-4.
La sécurisation d’un service Web se déroulera en trois étapes :
Voici par exemple le code du service Web ServiceStocks, développé au chapitre 8, après intégration du mécanisme de sécurisation:
ServicesStocks.asmx (Version VB.NET – Avec sécurisation)
Public class ServiceStocks : Inherits WebService
Public Class AuthHeader : Inherits SoapHeader
Public Username As String Public Password As String End Class
Public sHeader As AuthHeader
<WebMethod(EnableSession:=True),SoapHeader("sHeader")> Public Function AjouterMouvementStock(...)
If (sHeader Is Nothing)
Return "Erreur : absence d'informations d'authentification" End If
If (sHeader.Username <> "<YourID>") Or
X (sHeader.Password <> "<YourPwd")
Return "Erreur : authentification incorrecte"
End If
...
End Function
Du côté client, il suffit ensuite de générer le proxy correspondant (grâce à l’utili¬taire WSDL, voir chapitre précédent) et d’utiliser la propriété AuthHeaderValue (générée du fait de la présence de l’attribut SoapHeader) pour spécifier les infor¬mations d’authentification à transmettre au service:
Dim proxy As ServiceStocks = new ServiceStocks()
Dim authInfo As AuthHeader = new AuthHeader
authInfo.Username = "login" authInfo.Password = "password" proxy.AuthHeaderValue = authInfo proxy.AjouterMouvementStock(...)
Débogage et gestion des erreurs
Analyser l’exécution d’une application
Deux techniques sont possibles pour tracer l’exécution d’une application : l’utili¬sation de l’option Trace, très facile à mettre en œuvre mais limitée à l’affichage de messages décrivant les différentes étapes de l’exécution d’une page, et le recours au débogueur .NET, qui permet d’atteindre un niveau d’analyse avancé.
Accéder rapidement au déroulement détaillé avec l’option Trace
L’option Trace de la directive Page est le moyen le plus simple d’avoir une vision globale de l’exécution d’une page : lorsqu’elle est activée, un résumé complet des éléments liés à la requête (heure, identifiant de session, contenu de l’objet Session, encodage de la réponse...) et à l’exécution de la page (heures de début et de fin de l’exécution des principaux événements prédéfinis) est ajouté à la suite du contenu HTML produit.
En outre, l’utilisateur a la possibilité de rajouter des messages de trace au sein du code grâce aux méthodes Write et Warn de la propriété Trace de la classe Page, qui seront automatiquement ignorées si l’option Trace est désactivée.
Voici, par exemple, la marche à suivre pour tracer l’exécution de la page d’accueil de notre étude de cas, en étudiant en particulier le temps de réponse du service Web associé au contrôle Meteo développé dans le chapitre précédent:
<%@ Page Language="<YourLanguage>" Trace="True" %>
2 Insérez des instructions de trace (Trace.Write) pour encadrer les appels au service Web.
Fichier Meteo.ascx (Version C#)
Trace.Write("Contrôle météo","Avant GetWeatherInfos (Paris)");
infos = GetWeatherInfos("LFPO");
Trace.Write("Contrôle météo","Après GetWeatherInfos Paris");
...
Trace.Write("Contrôle météo","Avant GetWeatherInfos (Marseille)");
infos = GetWeatherInfos("LFML");
Trace.Write("Contrôle météo","Après GetWeatherInfos (Marseille)");
Si on exécute la page, on constate qu’elle est suivie d’un rapport complet des informations de trace, qui inclut les instructions spécifiées par l’intermédiaire de Trace.Write (figure 9-5).
Figure 9–5 Exécution d’une page avec activation de l’option Trace
Si le mécanisme de trace permet d’obtenir rapidement un grand nombre d’infor¬mations pertinentes, il ne permet pas de détailler pas à pas l’exécution d’une page : il faut pour cela recourir au débogueur.
Examiner en détail le déroulement de l’exécution avec le débogueur .NET
Le kit de développement .NET est fourni avec un débogueur gratuit et très puissant, qui possède pratiquement toutes les fonctionnalités du débogueur de Visual Studio.NET (à l’exclusion du Edit and Continue et du débogage d’appli-cations distantes) :
1 Démarrez le débogueur (voir remarque).
2 Ouvrez le fichier source correspondant à la page que vous souhaitez déboguer.
3 Choisissez Debug Processes... dans le menu Tools.
5 Positionnez au moins un point d’arrêt dans le code de la page (par exemple, dans le gestionnaire Page_Init ou Page_Load) afin de basculer dans le débo¬gueur lors de l’exécution de la page.
6 Enfin, exécutez la page dans un navigateur: le point d’arrêt s’active dans le débogueur (voir figure 9-7).
Optimiser les performances de l’application grâce au maintien en cache
ASP.NET offre la possibilité de configurer le maintien en cache d’une page ou d’un con¬trôle utilisateur en fonction de paramètres divers: délai de conservation dans le cache fixé par l’utilisateur, variation en fonction du type de navigateur utilisé (une nouvelle ver¬sion de la page est produite pour chaque nou¬veau navigateur, mais la version en cache est utilisée pour plusieurs requêtes successives émanant d’un même navigateur), de la pré¬sence de certains paramètres dans la chaîne de requête ou dans l’en-tête HTTP de la requête.
L’intérêt principal de ce mécanisme est d’opti¬miser les performances de l’application : par exemple, minimiser le temps d’affichage de la page d’accueil de notre intranet, qui contient le contrôle Meteo, lequel interroge le service GlobalWeather. En effet, le temps de réponse du service étant de plusieurs secon¬des et les données fournies n’étant mises à jour que toutes les deux heures, il est perti¬nent de maintenir en cache le résultat de l’exécution du contrôle.
Pour cela, il suffit d’ajouter la directive sui¬vante en haut de la page Meteo.ascx : où Duration spécifie le nombre de secondes pendant lequel il faut maintenir la version en cache (ici : deux heures).
D’autres options sont disponibles comme VaryByCustom, VaryByHeader, VaryByParam, qui permettent de paramétrer plus précisé¬ment la mise à jour du cache en fonction du navigateur, de l’en-tête HTTP ou de la chaîne de requête, comme précisé précédemment.
Tableau 9–1 Principales commandes utilisables dans le débogueur
Touche de raccourci F5 Action
Aller jusqu’au point d’arrêt suivant
F9 Créer ou supprimer un point d’arrêt
F10 Exécuter pas à pas sans entrer dans les fonctions appelées
F11 Exécuter pas à pas en entrant dans les fonctions appelées
Shift + F11 Sortir d’une fonction appélée
La gestion des exceptions
Tous les langages .NET permettent d’utiliser le mécanisme de gestion des exceptions, bien connu des programmeurs C++ et Java, afin de réaliser un traite¬ment de tous les cas d’erreurs, notamment ceux qui émanent d’éléments externes à l’application (fichiers introuvables, serveurs de données inaccessibles, services Web indisponibles...).
Le principe consiste à encadrer le code susceptible de générer des exceptions entre deux instructions Try et Catch, comme le montre l’exemple qui suit, ins-piré de la fonction ChargerListeFamilles développée au chapitre 4.
Stocks.aspx – (version VB.NET avec gestion des exceptions)
Sub ChargerListeFamilles()
Dim myConnection As SqlConnection Dim myCommand As SqlCommand
Dim myReader As SqlDataReader Dim SQL As String
Try
myConnection = CType(Session("myConnection"),SqlConnection)
SQL = "SELECT * FROM FamilleProduit" myCommand = new SqlCommand(SQL,myConnection)
myReader = myCommand.ExecuteReader()
ListeFamilles.DataSource = myReader
ListeFamilles.DataValueField = "ID_FamilleProduit" ListeFamilles.DataTextField = "NomFamille" ListeFamilles.DataBind()
myReader.Close()
Catch e As Exception
Response.Redirect("Erreur.aspx?message="+e.Message) End Try
End Sub
Notons que le développeur a également la possibilité de générer des exceptions à l’aide du mot-clé Throw, voire de définir ses propres types d’exceptions, dérivés de la classe ApplicationException définie dans l’espace de nommage System.
Gestion spécifique des erreurs
Parmi les types d’erreurs susceptibles de survenir lors de l’exécution d’une appli¬cation Web, on peut distinguer:
ASP.NET propose des solutions techniques pour gérer ces différents cas d’erreurs : il est possible de spécifier une page d’erreur personnalisée associée à un type d’erreur HTTP ainsi que d’intercepter l’ensemble des erreurs applica-tives au sein d’un gestionnaire d’événement Application_Error, afin de leur appliquer un traitement spécifique.
Spécifier une page d’erreur personnalisée
Pour spécifier une page d’erreur par défaut qui permette de notifier les dysfonc-tionnements de manière conviviale à l’utilisateur, il suffit d’insérer une section <customErrors> dans le fichier de configuration de l’application, en spécifiant:
Fichier web.config
<system.web>
<customErrors defaultRedirect="Erreur.aspx" mode="On"> <error statusCode="404" redirect="Erreur404.aspx"/> </customErrors>
</system.web>
Intercepter l’ensemble des erreurs survenant dans une application
Il est possible, par exemple, d’envoyer un message contenant la description de l’erreur à l’administrateur, tout en redirigeant l’utilisateur vers une page convi¬viale, comme le montre l’exemple de code proposé.
Fichier global.asax (version C#)
void Application_Error(Object sender, EventArgs E) {
MailMessage mail = new MailMessage();
mail.From = ""; mail.To = "<VotreAdresse>";
mail.Subject = "Une erreur ASP.NET s'est produite"; mail.Body = Server.GetLastError().ToString(); mail.BodyFormat = MailFormat.Text;
SmtpMail.SmtpServer = "<VotreServeurSMTP>"; SmtpMail.Send(mail);
Server.ClearError();
Response.Redirect("Erreur.aspx");
}
Après ce tour d’horizon des possibilités d’ASP.NET en matière de gestion d’erreurs, nous allons maintenant détailler le déploiement d’une application vers un serveur de production.
Déploiement d’une application ASP.NET
En pratique, une application ASP.NET est composée de deux types d’éléments :
Le mécanisme le plus simple pour déployer une application ASP.NET consiste à effectuer une simple copie des fichiers vers le répertoire de l’application sur la machine cible (les assemblages doivent être copiés dans le sous-répertoire bin).
Cette technique, présentée figure 9-9, présente deux avantages majeurs:
Figure 9–9 Déploiement d’une application ASP.NET
Déployer un assemblage dans le Global Assembly Cache
Avant de pouvoir être installé dans le Global Assembly Cache, un assemblage doit être signé numériquement à l’aide d’un mécanisme clé publique/clé privée, ceci pour deux raisons:
sn –k <NomFichier>
où <NomFichier> désigne le nom du fichier de clés à générer (auquel on donne généralement l’extension .snk).
sn.exe
Figure 9–10 Une des techniques possibles pour la signature d’un assemblage
Une fois la paire de clés générée, deux techniques sont disponibles pour signer un assemblage:
<Assembly: AssemblyKeyFile("MyKeyPair.snk")> (Version VB.NET) [assembly: AssemblyKeyFile("MyKeyPair.snk")] (Version C#)
gacutil –i <NomAssemblage>
Figure 9–12 Installation d’un assemblage dans le Global Assembly Cache
Droits spécifiques nécessaires
Contrairement au déploiement d’assemblages pri¬vés (XCOPY), l’installation d’un nouvel assemblage partagé dans le GAC nécessite d’avoir des droits spécifiques sur la machine cible (par exemple, accès en mode Terminal Server pour pouvoir exé¬cuter gacutil).
Localisation du Global Assembly Cache
Par défaut, le Global Assembly Cache est installé dans le répertoire \WINNT\assembly.
L’installation de l’assemblage peut être contrôlée grâce à l’utilitaire Microsoft .NET Framework Configuration, accessible via le dossier Outils d’administration du panneau de configuration, qui permet de visualiser l’ensemble des éléments présents dans le Global Assembly Cache (voir figure 9-13).
Figure 9–13 Visualisation du contenu du Global Assembly Cache
En résumé...
Dans ce dernier chapitre, nous avons passé en revue les principaux sujets relatifs à la sécurisation, la configuration, l’optimisation et la mise en production d’une application ASP.NET :