Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Thomas Lebrun

Tout sur WPF, LINQ, C# et .NET en général !

Actualités

[.NET] Appeler un objet COM tout en conservant l’impersonation

Voila une problématique que j’ai rencontré récemment et qui n’est pas aussi simple à régler que ce que l’on pourrait penser. Imaginer que l’on vous demande d’appeler un objet COM (tel que Analysis Services, au moyen de Microsoft.AnalysisServices.AdomdClient) mais qu’on vous impose de faire de l’impersonation (dans un service WCF par exemple) pour que vous puissiez tracer qui exécute la requête MDX.

Ni une, ni deux: vous mettez en place l’impersonation dans votre service WCF. Ainsi, vous commencez par rajouter cette ligne dans votre fichier web.config:

   1: <identity impersonate="true" />

Puis, dans votre code, vous récupérer l’Identity de l’utilisateur courant et vous appelez la méthode Impersonate:

   1: if (HttpContext.Current != null)
   2: {
   3:     if (HttpContext.Current.User != null)
   4:     {
   5:         if (HttpContext.Current.User.Identity != null)
   6:         {
   7:             IIdentity identity = HttpContext.Current.User.Identity;
   8:             WindowsIdentity windowsIdentity = identity as WindowsIdentity;
   9:             if (windowsIdentity != null)
  10:             {
  11:                 using (WindowsImpersonationContext wiCtx = windowsIdentity.Impersonate())
  12:                 {
  13:                     // Call to Analysis Services here
  14:                 }
  15:             }
  16:         }
  17:     }
  18: }

Vous exécutez votre code et là, en traçant les requêtes, vous vous apercevez que c’est un compte système qui exécute les requêtes: il semble donc y avoir un problème avec votre impersonnation…

En fait, il s’avère que votre code est correct. Le problème, expliqué ici, réside dans le fait que les objets COM utilise un modèle de thread STA (Single Thread Apartment) alors que votre service WCF, en .NET, utilise un modèle de thread MTA (Multithread Apartment). Si vous voulez connaitre la différence, jetez donc un oeil ici: http://stackoverflow.com/questions/127188/could-you-explain-sta-and-mta

Pour résoudre notre problème, la solution est simple: il suffit de créer un nouveau thread et de lui imposer de tourner en STA Smile

   1: theThread = new Thread(new ThreadStart(MySTAThreadStart));
   2:  
   3: // Intialize to an STA so that there will be no thread switch to the STA COM object.
   4: theThread.ApartmentState = ApartmentState.STA;

A partir de là, votre code appelera l’objet COM (Analysis Services) avec un modèle de thread STA ce qui permettra de conserver l’impersonnation !

 

Voila qui, je l’espère, permettra de gagner pas mal de temps à certains d’entre vous Smile

 

A+

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Posted: lundi 7 décembre 2009 10:20 par Thomas LEBRUN
Classé sous : ,

Commentaires

romain verdier a dit :

Juste un petit détail : pourquoi ne pas inverser les 3 premiers if, ou au moins fusionner les conditions ?

# décembre 7, 2009 11:01

Thomas LEBRUN a dit :

Parce que c'est un code d'exemple....

# décembre 7, 2009 11:09

Jb Evain a dit :

Comme ça on peut scroller pour le lire, on garde un peu de suspens !

En fait vous vous chamaillez pour des broutilles. Tout cela est facilement résolu à l'aide de l'opérateur trois petits points (...).

Exemple:

WindowsIdentity identity = ...;

using (WindowsImpersonationContext context = windowsIdentity.Impersonate())

{

 // Call to Analysis Services here

}

Et paf !

# décembre 7, 2009 12:58

Jb Evain a dit :

Vous aurez noter mon mauvais copier coller, signe que les blogs manquent de fonctionnalités de refactoring, mais moins que Visual Studio.

# décembre 7, 2009 13:02

Jb Evain a dit :

Et vous aurez noté ma faute de conjugaison aussi !

# décembre 7, 2009 13:06

Thomas LEBRUN a dit :

hum... je sens le débat intéressant et constructif à souhait qui s'annonce :)

# décembre 7, 2009 13:16

smo a dit :

Petite précision du pénible: la phrase "les objets COM utilisent un modèle de thread STA" est incorrecte. Les objets COM utilisent le modèle pour lequel ils ont été conçus par leur développeur (cela se trouve dans la registry en général). On peut tout à fait avoir un objet COM supportant le MTA ('Both' ou 'Free', c'est à dire qui s'adapte au modèle de threading de son client). En l'occurrence l'objet COM utilisé ici est vraisemblablement marqué comme 'Apartment', c'est le cas le plus fréquent (car le plus facile à développer).

# décembre 9, 2009 01:15
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- [SharePoint] Les sessions TechDays 2012… par Le blog de Patrick [MVP SharePoint] le il y a 6 heures et 26 minutes

- TechDays Paris 2012 : Session pleinière jour 3 par Blog Technique de Romelard Fabrice le 02-09-2012, 11:01

- Mishra Reader : un lecteur RSS très Zune Style en Open Source ! par Cyril Sansus le 02-09-2012, 08:28

- [framework 4] Les Tasks et le Thread UI par Fathi Bellahcene le 02-09-2012, 00:33

- Workflow Foundation 3 a un pied dans la tombe par Blog de Jérémy Jeanson le 02-08-2012, 22:15

- TechDays Paris 2012 : Nouvelles tendances du poste de travail - Bring Your own PC par Blog Technique de Romelard Fabrice le 02-08-2012, 19:42

- TechDays Paris 2012 : System Center Service Manager 2012 Vue d’ensemble par Blog Technique de Romelard Fabrice le 02-08-2012, 17:32

- TechDays Paris 2012 : Pleinière second jour par Blog Technique de Romelard Fabrice le 02-08-2012, 16:23

- TechDays Paris 2012 : Retour d'expérience sur la mise en place d'un Cloud Privé par Blog Technique de Romelard Fabrice le 02-08-2012, 16:04

- TechDays Paris 2012 : Comment SharePoint a sauvé mes TechDays par Blog Technique de Romelard Fabrice le 02-07-2012, 23:59