Олицетворение - доступ запрещен - PullRequest
1 голос
/ 26 марта 2010

У меня проблемы с использованием олицетворения для удаления PerformanceCounterCategory с веб-сайта MVC. У меня есть статический класс, и при запуске приложения он проверяет, существует ли PerformanceCounterCategory и содержит ли он правильные счетчики. Если нет, он удаляет категорию и создает ее снова с необходимыми счетчиками.

Он отлично работает при работе под встроенным веб-сервером Cassini, но при попытке запустить его через IIS7 (Vista) выдается следующая ошибка:

Доступ запрещен
Описание:
Произошло необработанное исключение во время выполнения текущего веб-запроса. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.
Сведения об исключении:
System.ComponentModel.Win32Exception: доступ запрещен

Мое использование кода:

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);

Код олицетворения из статьи 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);

Ошибка выдается, когда обработка пытается выполнить команду PerformanceCounterCategory.Delete.

Обновление
В ответ на ответ Дэвида я попытался сделать следующее:

  1. Создан новый локальный пользователь с именем PerfMonUser
  2. Добавил этого пользователя в группу «Пользователи системного монитора»

Изменен код, теперь он выглядит так:

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);

... но я все еще получаю ошибку:

Сведения об исключении: System.ComponentModel.Win32Exception: доступ запрещен

... на линии:

PerformanceCounterCategory.Delete(PerfCategory);

1 Ответ

2 голосов
/ 26 марта 2010

Это связано с тем, что PerformanceCounterCategory.Delete требует, чтобы у вас были либо права администратора, либо членство в группе пользователей системного монитора. Подробнее см. MSDN .

Cassini по умолчанию работает под учетной записью пользователя NT AUTHORITY \ SYSTEM, которая, очевидно, является Admin. Однако IIS работает под ограниченной учетной записью пользователя, поэтому у него не будет доступа к вызовам PerformanceCounter. Вам нужно будет сделать своего «пользовательского» пользователя участником Performance Monitor Users или администратором.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...