Как разрешить веб-службе WCF, которая использует олицетворение, записывать в журнал событий Windows?
Я пишу небольшой сервис WCF, и я хотел бы иметь возможность писать в пользовательский журнал событий. Я создал журнал событий и источник и минимальный сервис, и сервис может записывать в журнал. Затем я добавил олицетворение и начал получать ошибки "Доступ запрещен" на клиенте. При входе на сервер он принимает форму ошибки "Запрошенный доступ к реестру запрещен".
Хотя это не относится к пользователям службы, олицетворяемая учетная запись (обязательно) является членом Администраторов (чтобы иметь возможность отладки с использованием IIS).
Я получаю те же результаты, когда запускаю тестовый клиент WCF на той же машине с пользователем без прав администратора и на другой машине с пользователем без прав администратора.
Для воссоздания:
- Запустите PowerShell от имени администратора
- New-EventLog -LogName Test42 -Source Test42.Web
- Закрыть PowerShell
- Запустите Visual Studio от имени администратора
- Новый проект - .NET Framework 4.5 > Visual C# > WCF > Приложение службы WCF 'ImpSvc1' (* Создать каталог для решения)
- Замените содержимое IService1.cs, Service1.svc и Web.config содержимым ниже.
- В Свойствах проекта WCF> Веб (вкладка) > Серверы - выберите Локальный IIS и нажмите Создать виртуальный каталог.
- Постройте проект.
- Запустите IIS Manager - выберите веб-сайт по умолчанию
- Откройте IIS
- Вам понадобится пул приложений с учетной записью домена (без специальных разрешений на компьютере IIS) и интегрированным режимом конвейера, поэтому создайте его, если у вас его нет.
- Выберите Веб-сайт по умолчанию> Аутентификация. Убедитесь, что аутентификация Windows включена, а все остальные отключены.
- Выберите ImpSvc1 > Основные настройки. Выберите пул приложений сверху.
- Закройте IIS Manager.
- Запустите тестовый клиент WCF. Файл> Добавить службу> http://localhost/ImpSvc1/Service1.svc
- Дважды щелкните метод GetDate() и нажмите Invoke. Вы должны получить RESPONSE: user=; dateTime= и en событие, созданное в журнале событий Test42.
- Раскомментируйте оператор using, соберите и повторите Invoke, и вы должны получить: RESPONSE: user=; dateTime= и en событие, созданное в журнале событий Test42.
- Раскомментируйте оператор EventLog.WriteEntry, соберите и повторите Invoke, и вы должны получить ошибку "Доступ запрещен" в тестовом клиенте WCF.
- Если вы начнете проект с Debugging, вы увидите, что "Запрошенный доступ к реестру запрещен".
IService1.cs
using System;
using System.ServiceModel;
namespace ImpSvc1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
String GetData();
}
}
Service1.svc
using System;
using System.Diagnostics;
using System.Security.Principal;
using System.ServiceModel;
namespace ImpSvc1
{
public class Service1 : IService1
{
public String GetData()
{
EventLog.WriteEntry("Test42.Web", "Test message",
EventLogEntryType.Information, 1, 0);
//using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
//{
//EventLog.WriteEntry("Test42.Web", "Test message from using statement",
// EventLogEntryType.Information, 2, 0);
return String.Format("RESPONSE: user={0}; dateTime={1}",
WindowsIdentity.GetCurrent().Name, DateTime.Now);
//}
}
}
}
Web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext"
value="true" />
</appSettings>
<system.web>
<compilation debug="true"
targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding closeTimeout="00:05:00"
openTimeout="00:05:00"
receiveTimeout="00:10:00"
sendTimeout="00:10:00">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"
httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpBinding"
scheme="http" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<windowsAuthentication enabled="true" />
</authentication>
</security>
</system.webServer>
</configuration>