J'ai une application qui doit faire beaucoup d'usurpation d'identité, en raison du déplacement et de la création de nombreux fichiers sur des partages réseau protégés. J'ai créé une classe statique simple qui a une méthode qui prend un utilisateur, un domaine, un mot de passe et un délégué qui contient le code dont vous avez besoin dans le contexte de l'emprunt d'identité.Liaison d'assembly sous WindowsImpersonationContext. Comment empêcher FileLoadException?
Le problème que j'ai rencontré est lorsque le CLR tente de se lier à un assembly référencé dans ce contexte. Une exception FileLoadException est lancée avec un message "Accès refusé".
Je suis amené à croire que cela est dû au fait que l'utilisateur dont l'identité est empruntée ne dispose pas de privilèges suffisants pour le fichier * .DLL sous le système de fichiers. Par exemple, je peux écrire du code bénin juste avant le bloc d'emprunt d'identité, qui ne fait rien d'autre que de charger les types de l'assembly problème avant que le contexte ne bascule vers l'utilisateur emprunté, et cela fonctionne très bien! Cependant je ne considère pas vraiment que ce soit une solution élégante - est-ce que je vais devoir commencer à m'inquiéter des types que je peux employer sous l'emprunt d'identité, m'assurant que j'ai mis au hasard des déclarations typeof()
au préalable?
Ce qui rend cela plus frustrant, c'est que je ne rencontre pas ce problème sur ma machine de développement local. C'est lorsque les assemblys sont envoyés à l'environnement bêta que ce problème se produit. Et je n'ai pas accès à lire les autorisations de fichier de l'environnement bêta pour essayer de les imiter sur ma machine de localisation.
Dans tous les cas, j'ai essayé cette solution:
// Defined above:
// System.Security.Principal.WindowsIdentity identity;
// System.Security.Principal.WindowsImpersonationContext context;
context = identity.Impersonate();
int tries = 0;
while (true)
{
try
{
contextAction();
}
catch (FileLoadException ex)
{
if (tries > MAX_TRIES)
{
// don't allow an infinite loop
throw;
}
if (String.IsNullOrEmpty(ex.FileName))
{
// if this is null/empty, we can't really recover
throw;
}
context.Undo(); // return to current logon
try
{
var assemblyName = new AssemblyName(ex.FileName);
Assembly.Load(assemblyName);
tries++;
continue;
}
finally
{
context = identity.Impersonate(); // re-impersonate
}
}
finally
{
// return to your current windows logon
context.Undo();
}
}
Pas de dés. Je reçois toujours l'exception «Accès refusé», sauf maintenant à partir de la ligne commençant par Assembly.Load
.
Une chose intéressante à noter est que j'obtenais la même exception du serveur de construction. Cette solution ci-dessus l'a corrigé sur le serveur de construction. Pas dans notre environnement bêta.
Qu'est-ce qui me manque ici? Merci.