2010-03-26 22 views
1

Je rencontre des problèmes lors de l'utilisation de l'emprunt d'identité pour supprimer une PerformanceCounterCategory d'un site Web MVC. J'ai une classe statique et lorsque l'application démarre, elle vérifie si une PerformanceCounterCategory existe et si elle contient les compteurs corrects. Sinon, il supprime la catégorie et la crée de nouveau avec les compteurs requis.Emprunt d'identité - Accès refusé

Il fonctionne très bien lors de l'exécution sous la construction Cassini serveur web, mais quand je l'ai essayer courir à travers IIS7 (Vista) je reçois l'erreur suivante:

Access is denied
Description:
An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details:
System.ComponentModel.Win32Exception: Access is denied

Mon utilisation du code:

var username = "user"; 
var password = "password"; 
var domain = "tempuri.org"; 

WindowsImpersonationContext impersonationContext; 

// if impersonation fails - return 
if (!ImpersonateValidUser(username, password, domain, out impersonationContext)) 
{ 
    throw new AuthenticationException("Impersonation failed"); 
} 

PerformanceCounterCategory.Delete(PerfCategory); 
UndoImpersonation(impersonationContext); 

Le code d'emprunt d'identité d'un article MS ...

private static bool ImpersonateValidUser(string username, string password, 
    string domain, out WindowsImpersonationContext impersonationContext) 
{ 
    const int LOGON32_LOGON_INTERACTIVE = 2; 
    const int LOGON32_PROVIDER_DEFAULT = 0; 
    WindowsIdentity tempWindowsIdentity; 
    var token = IntPtr.Zero; 
    var tokenDuplicate = IntPtr.Zero; 

    if (RevertToSelf()) 
    { 
     if (LogonUserA(username, domain, password, 
      LOGON32_LOGON_INTERACTIVE, 
      LOGON32_PROVIDER_DEFAULT, ref token) != 0) 
     { 
      if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) 
      { 
       tempWindowsIdentity = new WindowsIdentity(tokenDuplicate); 
       impersonationContext = tempWindowsIdentity.Impersonate(); 

       if (impersonationContext != null) 
       { 
        CloseHandle(token); 
        CloseHandle(tokenDuplicate); 
        return true; 
       } 
      } 
     } 
    } 

    if (token != IntPtr.Zero) 
     CloseHandle(token); 
    if (tokenDuplicate != IntPtr.Zero) 
     CloseHandle(tokenDuplicate); 

    impersonationContext = null; 
    return false; 
} 



[DllImport("advapi32.dll")] 
public static extern int LogonUserA(String lpszUserName, String lpszDomain, 
    String lpszPassword, int dwLogonType, int dwLogonProvider, 
    ref IntPtr phToken); 

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel, 
    ref IntPtr hNewToken); 

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
public static extern bool RevertToSelf(); 

[DllImport("kernel32.dll", CharSet = CharSet.Auto)] 
public static extern bool CloseHandle(IntPtr handle); 

L'erreur est levée lorsque processi ng essaie d'exécuter la commande PerformanceCounterCategory.Delete.

Mise à jour
En réponse à la réponse de David i essayé ce qui suit:

  1. créé un nouvel utilisateur local nommé PerfMonUser
  2. Ajouté cet utilisateur au groupe "Utilisateurs de l'Analyseur de performances"

Modifié le code de sorte qu'il se lit maintenant:

var username = "PerfMonUser"; 
var password = "password"; 
var domain = Environment.MachineName; 

WindowsImpersonationContext impersonationContext; 

// if impersonation fails - return 
if (!ImpersonateValidUser(username, password, domain, out impersonationContext)) 
{ 
    throw new AuthenticationException("Impersonation failed"); 
} 

PerformanceCounterCategory.Delete(PerfCategory); 
UndoImpersonation(impersonationContext); 

... mais je reçois toujours l'erreur:

Exception Details: System.ComponentModel.Win32Exception: Access is denied

... sur la ligne:

PerformanceCounterCategory.Delete(PerfCategory); 

Répondre

2

C'est parce que PerformanceCounterCategory.Delete vous oblige à avoir soit des privilèges d'administrateur ou être membre du groupe Utilisateurs du moniteur de performances. Voir MSDN pour plus de détails.

Cassini s'exécute par défaut sous le compte d'utilisateur NT AUTHORITY \ SYSTEM, qui est évidemment Admin. IIS s'exécute toutefois sous un compte d'utilisateur limité, de sorte qu'il n'aura pas accès aux appels PerformanceCounter. Vous devez faire en sorte que votre utilisateur "utilisateur" soit un membre de Performance Monitor Users ou un administrateur.

+0

Vous avez dit avoir essayé d'ajouter l'utilisateur en tant que membre du groupe de moniteurs de performances. Avez-vous essayé d'ajouter cet utilisateur en tant qu'administrateur? Cela devrait être votre prochaine étape. Si cela fonctionne, alors vous savez que l'usurpation d'identité fonctionne bien, vous avez juste besoin de modifier les permissions. – sngregory