2015-11-04 82 views
1

我正在IIS上运行带有netMsmqBinding的WCF服务。它被配置为使用'Windows'客户端凭证类型的'消息'安全性,该类型使用kerberos来加密和签署消息。服务合同执行ProtectionLevel.EncryptAndSign。注意到交易正在从客户到服务使用可能很重要。由于kerberos时钟歪斜导致WCF服务延迟的MSMQ消息失败

服务运行时,通信工作完美无缺。但是,为了测试延迟消息的持久性或服务无法访问时,我暂时禁用了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票据来加密邮件,但由于WCF服务在10分钟后解密了邮件(至少),所以它检测到时钟歪斜。当然,我手动验证客户端和服务器上的时钟,但它们是相同的。

客户端配置:

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

这是怎么应该工作?我错过了什么?

编辑:

This page确实陈述一个事实,即“使用Kerberos协议进行排队通信的问题是,包含客户端身份票密钥分发中心(KDC)分配相对短生活。“,但它并没有详细阐述它何时有用。

关于kerberos邮件安全性的美妙之处在于,它几乎是开箱即用,有人应该考虑过这种情况,对吧?

编辑2:

我验证时两台服务器上和歪斜是用于在客户端约0.1秒(DC01是域控制器):

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.1020864s [       *       ] 
16:49:19 d:+00.0000000s o:-00.1020897s [       *       ] 
16:49:21 d:+00.0000000s o:-00.1020896s [       *       ] 
16:49:23 d:+00.0000000s o:-00.1020952s [       *       ] 
16:49:25 d:+00.0000000s o:-00.1021011s [       *       ] 

和服务器:

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 [       *       ] 

回答

0

嗯...听起来依稀有点像I blogged about。 45秒似乎是最大的延迟。

+0

我读到你使用公共队列,但我只需要私人队列。另外,我用时间同步信息更新了问题。这个问题只发生在信息延迟时(有意)。 – JohanG

+0

忽略对公共队列的引用 - 这是不重要的。这是使用Kerberos的相关性和时间的影响。例如,如果延迟时间仅为30秒,它会起作用,但不会持续一分钟吗? –

+1

啊,我可能误解了。我只测试了10秒,30秒,1分钟,2分钟,3分钟,4分钟和5分钟,只有5分钟的停机时间不起作用。我已经得出结论,kerberos并不意味着延迟信息。这也意味着5分钟的时间偏差不仅仅是为了补偿时钟差异,而且是运输时间。 – JohanG