首页 > 解决方案 > 如何允许使用模拟的 WCF Web 服务写入 Windows 事件日志?

问题描述

我正在编写一个小型 WCF 服务,并且希望能够写入自定义事件日志。我已经创建了一个事件日志和源以及一个最小的服务,并且该服务可以写入日志。然后我添加了模拟并开始在客户端收到“访问被拒绝”错误。在服务器上登录时,它采用“不允许请求的注册表访问”错误的形式。

尽管该服务的用户不会出现这种情况,但被模拟的帐户(必须)是管理员的成员(以便能够使用 IIS 进行调试)。

我在非管理员用户的同一台机器上和非管理员用户的另一台机器上运行 WCF 测试客户端得到相同的结果。

要重新创建:

  1. 以管理员身份启动 PowerShell
  2. New-EventLog -LogName Test42 -Source Test42.Web
  3. 关闭 PowerShell
  4. 以管理员身份启动 Visual Studio
  5. 新项目 - .NET Framework 4.5 > Visual C# > WCF > WCF 服务应用程序“ImpSvc1”(* 为解决方案创建目录)
  6. 将 IService1.cs、Service1.svc 和 Web.config 的内容替换为以下内容。
  7. 在 WCF Project Properties > Web (tab) > Servers - 选择 Local IIS 并单击 Create Virtual Directory。
  8. 构建项目。
  9. 启动 IIS 管理器 - 选择默认网站
  10. 打开 IIS
  11. 您需要一个具有域帐户(在 IIS 机器上没有特殊权限)和集成管道模式的应用程序池,因此如果您没有,请创建一个。
  12. 选择默认网站 > 身份验证。确保启用 Windows 身份验证并禁用所有其他身份验证。
  13. 选择 ImpSvc1 > 基本设置。从上方选择应用程序池。
  14. 关闭 IIS 管理器。
  15. 启动 WCF 测试客户端。文件 > 添加服务 > http://localhost/ImpSvc1/Service1.svc
  16. 双击 GetDate() 方法并单击 Invoke。你应该得到 RESPONSE: user=; dateTime= 和在 Test42 事件日志中创建的事件。
  17. 取消注释 using 语句,构建并重复调用,您应该得到: RESPONSE: user=; dateTime= 和在 Test42 事件日志中创建的事件。
  18. 取消注释 EventLog.WriteEntry 语句,构建并重复调用,您应该在 WCF 测试客户端中收到“访问被拒绝”错误。
  19. 如果您使用调试启动项目,您会看到它是“不允许请求的注册表访问”。

IService1.cs

using System;
using System.ServiceModel;

namespace ImpSvc1
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        String GetData();
    }
}

服务1.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);
            //}
        }
    }
}

网页配置

<?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>

标签: c#wcfcustom-eventlog

解决方案


推荐阅读