Исключение безопасности при вводе в EventLog из приложения ASP.NET MVC

У меня есть библиотека, которую я создал с помощью некоторой бизнес-логики, которая включает в себя запись в экземпляр System.Diagnostics.EventLog. Обычно библиотека вызывается из приложения Windows Service, но теперь я пытаюсь вызвать те же функции библиотеки из своего приложения ASP.NET MVC.

Я пробовал этот код внутри моего контроллера, чтобы создать экземпляр EventLog, который я передаю в метод, который нужно записать в журнал.

Dim log = New EventLog("Application", My.Computer.Name, "MyMVCApp")

Следующая ошибка возникает, когда код внутри метода библиотеки пытается записать в журнал:

[SecurityException: Requested registry access is not allowed.]
 System.ThrowHelper.ThrowSecurityException(ExceptionResource resource) +51
 Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable) +7462217
 System.Diagnostics.EventLog.CreateEventSource(EventSourceCreationData sourceData) +366
 System.Diagnostics.EventLog.VerifyAndCreateSource(String sourceName, String currentMachineName) +194
 System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData) +205
 System.Diagnostics.EventLog.WriteEntry(String message, EventLogEntryType type) +14

Мое веб-приложение работает как пользователь сетевой службы на Windows Server 2003 с запуском IIS 6. Есть ли что-то, что мне нужно сделать, чтобы предоставить пользователю Network Service доступ к реестру?

Есть ли лучший способ создать экземпляр EventLog для использования в приложении ASP.NET MVC? Есть ли кто-то, уже созданный каркасом, который мне просто нужно использовать?

Ответ 1

Из MSDN: "Приложения, которые запускаются с использованием идентификатора Сетевой службы, могут записываться в журнал событий с помощью существующих источников событий, но они не могут создать новое событие источники из-за недостаточных разрешений реестра.

А...

" Если источник для журнала событий, связанного с экземпляром EventLog , не существует, создается новый источник событий."

Так выглядит, что источник журнала событий не существует, и он пытается создать новый источник журнала событий, используя пользователя Network Service User (который требует записи в реестр, поэтому не работает).

"Чтобы приложение ASP.NET могло записывать в журнал событий с использованием источника событий, который еще не существует, у вас есть две возможности:"

  • Создание новых источников событий во время установки приложения
  • Вручную создать запись источника источника в реестре.

Итак, вам нужно создать журнал вне приложения (вы не можете делать это программно с этим пользователем. Сделайте это вручную или создайте простое приложение командной строки, чтобы упростить установку).

Подробнее:

http://msdn.microsoft.com/en-us/library/ms998320.aspx#paght000015_eventlogaccess

Лично я бы рекомендовал вам не изменять разрешения пользователя, а скорее создать источник журнала вне веб-приложения. Мое предпочтение - в консольном приложении (которое потребует от вас около 5 минут для записи и которое вы также можете использовать для подготовки других машин). Запустите новое консольное приложение в VS.NET и добавьте код для создания источников журнала. Пример:

http://www.dotnetspider.com/resources/23593-Create-Event-log-VB-NET.aspx

Затем просто запустите консольное приложение из строки cmd при входе в систему с соответствующими разрешениями.

Ответ 2

Если вы не знаете, какой источник событий пытается создать, то принятый ответ будет трудно понять.

Более простым решением было бы переключить пул приложений на временное использование LocalSystem, затем запустить приложение и создать ошибку. Он сможет создать соответствующий источник журнала событий, после чего вы можете переключить его обратно на использование NetworkService.

Ответ 3

Я не знаю, почему вы не можете создать свой собственный EventLog вместо записи в журнале приложений.

Вы можете создать окно/консольное приложение со следующим кодом и запустить его как администратор, это создаст для вас новый журнал.

if (!EventLog.Exists("LOG_NAME"))
   EventLog.CreateEventSource("LOG_NAME", "LOG_NAME");

это создаст новый журнал внутри журнала событий и будет отображаться в журналах приложений и сервисов.

 if (!EventLog.SourceExists("MyMVCApp"))
    EventLog.CreateEventSource("MyMVCApp", "LOG_NAME");

Это создаст новый источник внутри пользовательского "LOG_NAME", и вы сможете использовать код

Dim log = New EventLog("LOG_NAME", My.Computer.Name, "MyMVCApp")

чтобы создать собственный журнал.