Comment impersonifier temporairement l’identité du AppPool en ASP.Net

Il est fréquent d’impersonifier l’identité du l’utilisateur dans une application ASP.Net MVC. L’application est personnalisée ou sécuritée par utilisateur ce qui nous empêche d’impersonifier un compte de service précis.

Normalement, avec une connaissance de Kerberos, il est facile de faire en sorte que l’identité de l’utilisateur voyage jusqu’aux différents serveurs de données (SQL Server, Analysis Services etc.).

Mais dans certains cas, la délégation Kerberos n’est pas envisageable. C’est en autre le cas pour l’API qui se trouve dans System.DirectoryServices. Cet API permet d’interroger Active Directory afin d’obtenir les groupes dont un utilisateur fait partie ou d’aller chercher des propriétés etc.

Même si cet API est en .NET, ça semble utiliser des fonctonnalités COM et il semblerait que la délégation Kerberos n’est pas supportée dans ce scénario. En effet, lors d’un Double Hop, l’erreur suivante est obtenue lors de l’utilisation des classes de System.DirectoryServices:

[COMException (0x80072020): An operations error occurred. ]

Le KB329986propose des solutions mais aucune ne nous semblait acceptable pour notre besoin (ex. utiliser l’authentification basique).

Heureusement, nos applications ASP.Net MVC s’exécutent sous un AppPool ayant une identité d’un compte de domaine (le même que pour SharePoint lorsque l’application MVC est hébergée sous SharePoint). Il est possible d’exécuter un bloc de code sous l’identité du compte de service du AppPool en utilisant:

using (HostingEnvironment.Impersonate()) {

// Ce code s’exécute avec l’identité
// assignée au pool d’application (AppPool)

DirectorySearcher searcher …
}

Il faut ajouter une référence àSystem.Web.dll et faire un usingSystem.Web.Hosting.

Cette technique a l’avantage de contrôler les lignes de code devant s’exécuter sous le compte du AppPool. Tout le reste peut continuer de s’exécuter sous l’identité de l’utilisateur du fureteur.

Dans le cas précis de l’accès à Active Directory, cette technique offre un autre avantage. Plutôt que d’avoir à donner accès en lecture à Active Directory à tous vos utilisateurs, vous pouvez accorder ce droit uniquement au compte de domaine assigné au AppPool.

Références

How to use the System.DirectoryServices namespace in ASP.NET

Quelles sont les compétences nécessaires pour être un bon développeur ASP.Net MVC?

Vous avez un projet pour une application Web incluant de la saisie de données? Vous cherchez des ressources internes ou externes pour réaliser la solution? Quelles sont les aptitudes techniques qui doivent être maîtrisées et du moins à apprendre par les ressources identifiées?

Plutôt que de créer une couche d’abstraction par dessus le DHTML, Microsoft a plutôt créé un environnement qui facilite sa génération. Ainsi, comme les technologies Web évoluent vite, les projets ASP.Net MVC peuvent en profiter immédiatement plutôt que d’attendre que la couche d’abstraction soit mise à jour.

Ainsi, il faut d’abord maîtriser les éléments suivants avant de se lancer dans le développement ASP.Net MVC:

Technologie Raisonnemment
HTML Le contenu des pages, une partie de la structure ainsi que les formulaires sont tous définis en HTML.
CSS Idéalement le formatage est défini dans des fichiers de styles externes afin de faciliter la maintenance et les changements importants de look.
JavaScript Peu de sites Web en 2012 n’ont pas besoin du JavaScript pour effectuer des validations, de la logique applicative ou de la transformation d’éléments HTML simples en contrôles interactifs.Ce code s’exécute sur le poste client (fureteur).
C# ou VB.Net Un projet ASP.Net est bâti en utilisant un language du .Net Framework. Il s’agit du code qui s’exécute sur le serveur et non sur le poste client.
SQL et base de données La plupart des projets ASP.Net se connectent sur des bases de données afin d’obtenir ou modifier de l’information. Un développeur doit connaître ces éléments.

Ensuite, il faudra prendre le temps d’apprendre les éléments suivants:

Technologie Raisonnemment
MVC Il s’agit d’une manière de structurer le projet, la logique applicative et le traitement des Urls.En bref:- Les modèles devraient contenir les classes qui représentent les données et la logique d’affaires de l’application à créer.

– Les vues savent comment afficher un modèle donné. Il peut s’agir de générer du HTML, du Xml, du JSON + JavaScript (ex. Sencha Charts). La vue connaît le modèle et sait comment référer aux controlleurs via des hyperliens.

– Les controlleurs sont appelés à partir des règles de “Routing”. La plomberie ASP.Net MVC va transformer un hyperlien en un appel de méthode dans une classe de controlleur avec une correspondance automatique des paramètres (et même leur conversion). Le rôle des controlleurs est d’obtenir tous les paramètres de la requête, d’aller chercher/ créer le modèle et de retourner une vue en lui passant le modèle.

Razor Avant “Razor”, on utilisait les “Web Form” et c’était difficile de distinguer le contenu HTML du code. Ce language permet de mixer du HTML et du code de manière optimale avec des @if, @switch, @foreach etc. On aime tout de suite ce langage en l’utilisant …
LINQ To SQL Microsoft a fait un excellent travail en créant LINQ qui évite d’avoir à concaténer des chaînes de caractères pour créer des requêtes SQL. Avec les “Nullable Types” (ex. int?, double?), le C# devient un langage de premier niveau pour du développement utilisant des bases de données.LINQ To SQL permet de créer une couche d’accès aux données simplement en important la définition des tables à partir de la base de données. Souvent le développeur ajoutera des méthodes à la classe DataContext (vive les classes partielles) qui seront des facilitants pour l’obtention, l’ajout et surtout la destruction des différentes entités. Mais on est loin de l’époque où il fallait écrire les couches de données à partir de zéro …

Cela fait déjà beaucoup de chose à apprendre. Mais ce n’est pas tout. En 2012, on ne peut plus afficher de simples contrôles Html (ListBox, TextBox etc.)

Les utilisateurs s’attendent à avoir des contrôles évolués tels que:

ListBox à sélection multiple:
image
http://www.quasipartikel.at/multiselect/

Calendrier avec l’heure:
image
http://trentrichardson.com/examples/timepicker/

Et c’est pourquoi je me dois d’ajouter JQuery à la liste des compétences nécessaires. Cette librairie permet de laisser le HTML le plus près possible de “ce qu’il représente” (ex. un ListBox à sélection multiple) et d’utiliser du JavaScript pour venir le transformer directement en un contrôle évolué. Souvent une seule ligne peut suffire:

$(‘#example1’).datetimepicker();

Bonne chance dans votre apprentissage ou votre recherche de candidats!

Intégrer une application ASP.Net MVC 3 sous un site Web IIS hébergeant SharePoint Server 2010

SharePoint Foundation / Server 2010 utilisent le .NET Framework 3.5. Même si le pool d’application indique 2.0, SharePoint charge la version 3.5.

image

Les projets de développement Web récents utilisent souvent ASP.Net MVC 3 avec le .NET Framework 4.0. J’avais donné la recette pour intégrer ce type de projet sous WSS 3.0 / SharePoint 2007 mais il y a quelques étapes qui sont différentes avec 2010. En bleu j’ai mis les nouveaux éléments et en orange ceux qui sont un peu différents. Les étapes qui ne sont pas nécesaires ont été enlevées tout simplement.

  1. Vous devez créer un “Application Pool” utilisant le “.NET Framework 4.0” et empruntant la même identité (le même compte de service) que l’ “Application Pool” de SharePoint.Puisque le site IIS a un SPN unique (ex. HTTP/nomgentil.domaine.com), celui-ci est déjà défini sur le compte de service en question. Ainsi, il suffira d’ajouter la déléguation vers SQL Server ou SSAS à ce compte selon ce que fait l’application ASP.Net.
  2. Vouspouvezcopier le répertoire de votre application ASP.Net sous le répertoire contenant SharePoint. Ex. C:\Inetpub\wss\nomgentil.domain.com\ApplicationMVCNote: Vous pouvez le mettre ailleurs mais cela fonctionne très bien à cet endroit.
  3. Les permissions par défaut ne sont pas les même que pour les sites placés directement sous C:\Inetpub alors assurez-vous de donner les permissions Windows à Users ou autre au répertoire de votre application MVC.
  4. Il faut convertir le virtual directory en application dans IIS en prenant bien soin d’utiliser le pool d’application défini précédemment.
  5. Une application ASP.Net utilise un fichier Web.Config afin de configurer différents éléments propres à .Net. Ce qu’il faut savoir c’est qu’il y a un lien d’héritage entre les Web.Config des applications Web. Ainsi si l’application B est placée sous l’application A dans IIS, elle hérite du Web.Config.Le problème c’est qu’en étant sous SharePoint, on hérite de certains éléments incompatibles avec une application utilisant le “.NET Framework 4.0”.

    Il faut donc modifier le web.config de SHAREPOINT pour indiquer qu’on ne souhaite pas hériter de certaines sections dans les sites enfants. Plus spécifiquement, il faut entourer les noeuds <microsoft.sharepoint.client>, <SharePoint>,  <system.web>, <System.Workflow.ComponentModel.WorkflowCompiler>, <ReportingServices>, <system.web.extensions>, <Bpm> et <reportserver> d’un noeud <location path=”.” inheritInChildApplications=”false”>. Par exemple:

    <location inheritinchildapplications= »false » path= ». »>
    <system.web>…</system.web>
    </location>

     

  6. Il faut maintenant déplacer l’élément Xml <sectionGroup> nommé “system.web.extensions” du Web.Config de SharePoint vers le Web.Config qui se trouve à cet endroit: C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG\Web.Config.

    On doit le mettre sous le noeud <configSections> directement sous <configuration>:

    <configuration>
    <configSections>
    <sectionGroup name= »system.web.extensions » …

    La raison est que le site ASP.Net MVC 3 .NET 4 hérite du Web.Config de SharePoint et ce sectionGroup cause une erreur. On ne peut pas utiliser l’élément <location> à cet endroit. En déplaçant la déclaration directement dans le Web.Config du .NET Framework 2.0, SharePoint en héritera mais pas notre application ASP.Net.

    Vous pouvez obtenir plus d’information ici. Un extrait:

    Move the configSections definition in the Web.config file of the parent application (the application that runs ASP.NET 2.0 or ASP.NET 3.5) into the root Web.config file for the.NET Framework 2.0. The IIS 7 and IIS 7.5 native configuration system scans the configSections element when it merges the hierarchy of configuration files. Moving the configSections definition from the parent Web application’s Web.config file to the root Web.config file effectively hides the element from the configuration merge process that occurs for the child ASP.NET 4 application.

  7. On hérite aussi des Modules du site SharePoint et ceux-ci causent une erreur (en particulier SharePoint14Module). La solution est d’utiliser ce noeud <modules> dans votre application ASP.Net:

    <modules runAllManagedModulesForAllRequests= »true »>
    <remove name= »SPRequestModule » />
    <remove name= »PublishingHttpModule » />
    <remove name= »RSRedirectModule » />
    <remove name= »StateServiceModule » />
    <remove name= »SharePoint14Module » />
    <add name= »Session » type= »System.Web.SessionState.SessionStateModule » />
    </modules>

    Notez qu’en plus d’enlever les modules spécifiques à SharePoint, on réactive la gestion des Session. Si vous ne le faites pas, vous ne pourrez pas utiliser l’objet Session.

    En fait, comme on ne peut pas utiliser la clause <location> pour <system.webServer>, il faut défaire ce qui est fait par SharePoint. Il se peut que votre implantation nécessite d’activer / désactiver certains modules / “Http Handlers”. Voici un extrait de ce que SharePoint active / désactive:

    <modules runAllManagedModulesForAllRequests= »true »>
    <remove name= »AnonymousIdentification » />
    <remove name= »FileAuthorization » />
    <remove name= »Profile » />
    <remove name= »WebDAVModule » />
    <remove name= »Session » />
    <add name= »SPRequestModule » … />
    <add name= »ScriptModule »  … />
    <add name= »SharePoint14Module » … />
    <add name= »StateServiceModule » … />
    <add name= »RSRedirectModule » … />
    <add name= »PublishingHttpModule » … />
    </modules>
    <handlers>
    <remove name= »OPTIONSVerbHandler » />
    <remove name= »WebServiceHandlerFactory-Integrated » />
    <remove name= »svc-Integrated » />
    <remove name= »WebDAV » />
    <add name= »svc-Integrated » … />
    <add name= »OwssvrHandler » … />
    <add name= »ScriptHandlerFactory » … />
    <add name= »ScriptHandlerFactoryAppServices » … />
    <add name= »ScriptResource » …  />
    <add name= »JSONHandlerFactory » … />
    <add name= »ReportViewerWebPart » … />
    <add name= »ReportViewerWebControl » … />
    </handlers>

     

  8. IIS Reset
  9. Si vous avez une erreur qui dit que le fichier de configuration n’est pas accessible, donnez temporairement les droits en lecture au groupe local IIS_IUSRS sur ce fichier (l’erreur indique le chemin d’accès).

    Quand IIS n’arrive pas à déterminer l’authentification utilisée (ex. il y a un nœud dupliqué dans les web.config parent et enfant), il doit avoir accès en mode anonyme. Après l’erreur qui sera affichée sera détaillée (ex. le nœud qui ne peut être redéfini etc.)

  10. Si vous avez une erreur HTTP 500 ou une page blanche, même avec customErrors à OFF, vous pouvez utiliser la fonctionnalité des Failed Request Tracing (FREB). Voici comment l’activer pour un site / application.

    C’est ainsi que j’ai su qu’il me fallait désactiver le module SharePoint14Module:

    Request Diagnostics HTTP 500

Bref, oui c’est possible de mettre une application ASP.Net MVC 3 sous SharePoint 2010 mais il faut quand même effectuer un certain nombre de manipulations …

Bonne chance et à la prochaine …

Comment désactiver AboMapperCustom-xxxxxxxxxx lors du déploiement d’une application ASP.Net MVC 3 sous SharePoint?

Dans mon billet “Intégrer une application ASP.Net MVC sous un site Web IIS hébergeant WSS 3.0 / SharePoint 2007” j’indiquais les étapes nécessaires au déploiement d’une application ASP.Net MVC 3 sous SharePoint. L’une d’entre elle était d’enlever manuellement une entrée des “Handler Mappings”. Le problème c’est que lorsqu’on redéploie l’application (ex. via le Publish de Visual Studio 2010), cette modification manuelle est perdue et il faut se rappeler de l’appliquer.

En cherchant une solution au problème j’ai trouvé une fonctionnalité qui ouvre la porte à d’autre possibilités: on peut appliquer une transformation au fichier web.config à partir d’un fichier de transformation (syntaxe xml). Cette configuration est appliquée au fichier web.config lors du déploiement.

Dès lors qu’on ajoute des configurations (par défaut nous avons Debug et Release) :

image

image

image

il est possible d’utiliser la commande “Add Config Transforms”:

image

Ce qui ajoute automatiquement un fichier de configuration qu’on peut ajuster à nos besoins.

image

On peut s’en servir pour changer les chaînes de connexion.

<connectionStrings>
<add
name= »TPMSDataEntryConnectionString »
providerName= »System.Data.SqlClient »
connectionString= »<Configuration Specific ConnStr> »
xdt:Transform= »SetAttributes »
xdt:Locator= »Match(name) »/>
</connectionStrings>

Mais on peut aussi s’en servir pour enlever le détestable AboMapperCustom-xxxxxxxxxx:

<system.webServer xdt:Transform= »Replace »>
<validation validateIntegratedModeConfiguration= »false »/>
<modules runAllManagedModulesForAllRequests= »true »/>
<handlers>
<remove name= »AboMapperCustom-3515455823″ />
</handlers>
</system.webServer>

Lorsque vous êtes prêt à publier votre application, il faut simplement vous souvenir de sélectionner la bonne configuration avant d’utiliser “Publish” ou “Build Deployment Package”

Allez consulter les articles dans mes références pour une introduction plus complète sur les fichiers de transformation ou pour obtenir la documentation du schéma.

Références

How to: Transform Web.config When Deploying a Web Application Project
http://msdn.microsoft.com/en-us/library/dd465318.aspx

Web.config Transformation Syntax for Web Application Project Deployment
http://msdn.microsoft.com/en-us/library/dd465326.aspx

Transforming Web.config For Different Environments
http://maperry2009.blogspot.ca/2010/03/transforming-webconfig-for-different.html

Intégrer une application ASP.Net MVC sous un site Web IIS hébergeant WSS 3.0 / SharePoint 2007

WSS 3.0 et MOSS 2007 utilisent le .NET Framework 2.0. Les projets de développement Web récents utilisent souvent ASP.Net MVC avec le .NET Framework 4.0. Il y a quelques éléments à configurer pour faire fonctionner une application ASP.Net 4.0 sous SharePoint. Voici la recette:

  1. Vous devez créer un « Application Pool” utilisant le “.NET Framework 4.0” et empruntant la même identité (le même compte de service) que l’ “Application Pool” de SharePoint.Puisque le site IIS a un SPN unique (ex. HTTP/nomgentil.domaine.com), celui-ci est déjà défini sur le compte de service en question. Ainsi, il suffira d’ajouter la déléguation vers SQL Server ou SSAS à ce compte selon ce que fait l’application ASP.Net.
  2. Vous devez copier le répertoire de votre application ASP.Net sous le répertoire contenant SharePoint. Ex. C:\Inetpub\wss\nomgentil.domain.com\ApplicationMVC
  3. Les permissions par défaut ne sont pas les même que pour les sites placés directement sous C:\Inetpub alors assurez-vous de donner les permissions Windows à Users ou autre au répertoire de votre application MVC.
  4. Il faut convertir le virtual directory en application dans IIS en prenant bien soin d’utiliser le pool d’application défini précédemment.
  5. Une application ASP.Net utilise un fichier Web.Config afin de configurer différents éléments propres à .Net. Ce qu’il faut savoir c’est qu’il y a un lien d’héritage entre les Web.Config des applications Web. Ainsi si l’application B est placée sous l’application A dans IIS, elle hérite du Web.Config.Le problème c’est qu’en étant sous SharePoint, on hérite de certains éléments incompatibles avec une application utilisant le “.NET Framework 4.0”.

    Il faut donc modifier le web.config de SHAREPOINT pour indiquer qu’on ne souhaite pas hériter de certaines sections dans les sites enfants. Plus spécifiquement, il faut entourer les noeuds <system.web> et <System.Workflow.ComponentModel.WorkflowCompiler> d’un noeud <location path= ». » inheritInChildApplications= »false »>. Par exemple:

    <location path= ». » inheritInChildApplications= »false »>
    <system.web>

    </system.web>
    </location>

  6. On hérite aussi des “Handler Mappings” du site SharePoint et il y en a beaucoup. Il faut au moins enlever (dans l’application ASP.Net MVC) celui qui intercepte * et qui porte le nom AboMapperCustom-<numéro> pointant vers ASP.Net 2.0 (aspnet_isapi.dll). Autrement les images, CSS et autres fichiers statiques ne fonctionneront pas.image

    Cela aura pour effet d’ajouter ceci au web.config de votre application:

    <handlers>
    <remove name= »AboMapperCustom-3515455823″ />
    </handlers>

  7. IIS Reset
  8. Si vous avez une erreur qui dit que le fichier de configuration n’est pas accessible, donnez temporairement les droits en lecture au groupe local IIS_IUSRS sur ce fichier (l’erreur indique le chemin d’accès).Quand IIS n’arrive pas à déterminer l’authentification utilisée (ex. il y a un nœud dupliqué dans les web.config parent et enfant), il doit avoir accès en mode anonyme. Après l’erreur qui sera affichée sera détaillée (ex. le nœud qui ne peut être redéfini etc.)

Références
Troubleshooting HTTP 500.19 Errors in IIS 7
http://blogs.iis.net/webtopics/archive/2010/03/08/troubleshooting-http-500-19-errors-in-iis-7.aspx