由于kerberos时钟偏移,发送到WCF服务的延迟MSMQ消息失败

由于kerberos时钟偏移,发送到WCF服务的延迟MSMQ消息失败,wcf,iis,msmq,kerberos,netmsmqbinding,Wcf,Iis,Msmq,Kerberos,Netmsmqbinding,我正在IIS上运行带有netMsmqBinding的WCF服务。它被配置为对“Windows”客户端凭据类型使用“消息”安全性,该类型使用kerberos对消息进行加密和签名。服务合同强制执行ProtectionLevel.EncryptAndSign。可能需要注意的是,事务正在从客户机到服务之间使用 当服务运行时,通信将完美地工作。但是,为了测试延迟消息的持久性或当无法访问服务时,我临时禁用了IIS中服务的应用程序池。然后我从客户端发送一条消息。它离开客户机上的传出队列,并传输到服务器上的专用

我正在IIS上运行带有netMsmqBinding的WCF服务。它被配置为对“Windows”客户端凭据类型使用“消息”安全性,该类型使用kerberos对消息进行加密和签名。服务合同强制执行ProtectionLevel.EncryptAndSign。可能需要注意的是,事务正在从客户机到服务之间使用

当服务运行时,通信将完美地工作。但是,为了测试延迟消息的持久性或当无法访问服务时,我临时禁用了IIS中服务的应用程序池。然后我从客户端发送一条消息。它离开客户机上的传出队列,并传输到服务器上的专用队列。.NET MSMQ侦听器拾取消息并尝试调用WCF服务方法,但如预期的那样失败。大约10分钟后,我重新启动了应用程序池。在服务跟踪日志中,记录了以下异常:

System.ServiceModel.Security.MessageSecurityException:
"Message security verification failed."
  System.IdentityModel.Tokens.SecurityTokenException:
  "The AcceptSecurityContext failed."
    System.ComponentModel.Win32Exception:
    "The clocks on the client and server machines are skewed"
我还尝试了相同的场景,将服务器上的消息队列服务脱机。结果是一样的

我的猜测是,客户端获得kerberos票证来加密消息,但由于消息在10分钟后(至少)被WCF服务解密,因此它检测到时钟偏移。当然,我手动验证了客户端和服务器上的时钟,但它们是相同的

客户端配置:

<bindings>
  ...
  <netMsmqBinding>
    <binding>
      <security mode="Message">
        <message clientCredentialType="Windows" />
      </security>
    </binding>
  </netMsmqBinding>
</bindings>

<client>
  ...
  <endpoint address="net.msmq://host/private/service/service.svc"
            binding="netMsmqBinding"
            contract="Namespace.Contract" />
</client>
<bindings>
  ...
  <netMsmqBinding>
    <binding receiveErrorHandling="Reject">
      <security mode="Message">
        <message clientCredentialType="Windows" />
      </security>
    </binding>
  </netMsmqBinding>
</bindings>

<serviceActivations>
  ...
  <add relativeAddress="service.svc"
       service="Namespace.Contract"
       factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory"/>
</serviceActivations>

<services>
  ...
  <service name="Namespace.Contract">
    <endpoint address="net.msmq://localhost/private/service/service.svc"
              binding="netMsmqBinding"
              contract="Namespace.IContract" />
  </service>
</services>
和服务器:

C:\>w32tm /stripchart /computer:DC01 /samples:5
Tracking DC01 [10.1.1.2:123].
Collecting 5 samples.
The current time is 04-11-2015 16:49:17.
16:49:17 d:+00.0000000s o:-00.1171919s  [                           *                           ]
16:49:19 d:+00.0000000s o:-00.1360460s  [                           *                           ]
16:49:21 d:+00.0000000s o:-00.1237094s  [                           *                           ]
16:49:23 d:+00.0000000s o:-00.1269640s  [                           *                           ]
16:49:25 d:+00.0000000s o:-00.1302236s  [                           *                           ]

嗯。。。听起来有点像什么。45秒似乎是最大延迟

嗯。。。听起来有点像什么。45秒似乎是最大延迟

我听说你使用公共队列,但我只需要私人队列。另外,我用时间同步信息更新了问题。该问题仅在消息延迟(故意)时发生。忽略对公共队列的引用-这并不重要。Kerberos的使用是相关的,并且是时间的影响。例如,如果你只延迟30秒,而不是一分钟,它是否有效?啊,我可能误解了。我只是测试了10秒、30秒、1分钟、2分钟、3分钟、4分钟和5分钟,只有5分钟的“停机时间”不起作用。我已经得出结论,kerberos并不适用于延迟消息传递。这也意味着5分钟的“时钟偏移”不仅是为了补偿时钟差异,也是为了补偿传输时间。我听说你们使用公共队列,但我只需要私人队列。另外,我用时间同步信息更新了问题。该问题仅在消息延迟(故意)时发生。忽略对公共队列的引用-这并不重要。Kerberos的使用是相关的,并且是时间的影响。例如,如果你只延迟30秒,而不是一分钟,它是否有效?啊,我可能误解了。我只是测试了10秒、30秒、1分钟、2分钟、3分钟、4分钟和5分钟,只有5分钟的“停机时间”不起作用。我已经得出结论,kerberos并不适用于延迟消息传递。这也意味着5分钟的“时钟偏移”不仅是为了补偿时钟差异,也是为了补偿传输时间。
C:\>w32tm /stripchart /computer:DC01 /samples:5
Tracking DC01 [10.1.1.2:123].
Collecting 5 samples.
The current time is 04-11-2015 16:49:17.
16:49:17 d:+00.0000000s o:-00.1171919s  [                           *                           ]
16:49:19 d:+00.0000000s o:-00.1360460s  [                           *                           ]
16:49:21 d:+00.0000000s o:-00.1237094s  [                           *                           ]
16:49:23 d:+00.0000000s o:-00.1269640s  [                           *                           ]
16:49:25 d:+00.0000000s o:-00.1302236s  [                           *                           ]