如何使WCF服务的服务器 - 客户端的时间差独立?时间差、客户端、独立、服务器

2023-09-04 00:43:32 作者:玩家

虽然从测试客户端访问WCF服务,我得到以下异常:

  System.ServiceModel.Security.MessageSecurityException:无抵押或担保不正确的故障是由对方收到。请参阅故障code和详细的内部FaultException异常。 ---> System.ServiceModel.FaultException:该消息确认安全时发生错误。
   ---内部异常堆栈跟踪的结尾---
 

我搜索在互联网上这个问题的根本原因。我发现,这主要是由于客户端 - 服务器的时间差而引起的。但我无法找到正确的解决之道。以下是我的服务器端配置:

 < system.serviceModel>
    <绑定>
      <的wsHttpBinding>
        <绑定名称=RequestUserName>
            <安全模式=消息>
              <消息clientCredentialType =窗口negotiateServiceCredential =真正的establishSecurityContext =真/>

            < /安全>
        < /装订>
      < /的wsHttpBinding>

    < /绑定>
    <服务>
      <服务名称=WCFService.Service1behaviorConfiguration =WCFService.Service1Behavior>
        <! - 服务端点 - >
        <端点地址=htt​​p://subdomain.domain.com/service1.svc绑定=的wsHttpBinding合同=WCFService.IService1bindingName =RequestUserName>


        < /端点>
        <端点地址=MEX绑定=mexHttpBinding合同=IMetadataExchange接口/>

      < /服务>
    < /服务>
    <行为>
      < serviceBehaviors>
        <行为NAME =WCFService.Service1Behavior>
          <! - 为了避免泄露的元数据信息,在部署之前设置以下为假的价值 - >
          < serviceMetadata httpGetEnabled =FALSE/>

          <! - 要接收故障异​​常详细信息以进行调试,设置以下为true值。设置为false部署之前,以避免泄露异常信息 - >
          < serviceDebug includeExceptionDetailInFaults =FALSE/>

        < /行为>
      < / serviceBehaviors>
    < /行为>
    < serviceHostingEnvironment>
      < baseAddress prefixFilters>
        <增加preFIX =htt​​p://subdomain.domain.com//>
      < / baseAddress prefixFilters>
    < / serviceHostingEnvironment>
 

和客户端配置:

 < XML版本=1.0编码=UTF-8&GT?;
<结构>
    < system.serviceModel>
        <绑定>
            <的wsHttpBinding>
                <绑定名称=RequestUserName_IService1/>
            < /的wsHttpBinding>
        < /绑定>
        <客户端>
            <端点地址=htt​​p://subdomain.domain.com/service1.svc绑定=的wsHttpBinding
                bindingConfiguration =RequestUserName_IService1合同=ServiceReference1.IService1
                NAME =RequestUserName_IService1>
                <身份>
                    <通过UserPrincipalName值=域\ subdomaincom_web/>
                < /身分>
            < /端点>
        < /客户>
    < /system.serviceModel>
< /结构>
 
wcf服务器用户识别, 捕获WCF服务端与客户端产生的通讯数据并分析

请人帮我找到解决这个问题。

更新::当我跟踪的异常,内部异常将显示有关安全时间戳是陈旧的,因为它的截止时间(2013-08-21T11:17:39.482 Z')是在过去。当前时间是'2013-08-21T12:31:31.897Z,并允许时钟偏斜是'00:05:00

我的服务器使用UTC格式和我的客户是可以从任何一个国家可以下载一个通用的应用程序。

更新2:配置答案后:

 < system.serviceModel>
    <绑定>
      < customBinding>
        <绑定名称=Wrabind>
          < transactionFlow />
          <安全authenticationMode =安全会话 messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
            < localClientSettings maxClockSkew =0点07分00秒/>
            < localServiceSettings maxClockSkew =○时○七分00秒/>
            < secureConversationBootstrap messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" />
                < localClientSettings maxClockSkew =00:30:00/>
                < localServiceSettings maxClockSkew =00:30:00/>
          < /安全>
          < textMessageEncoding />
          < httpTransport />
        < /装订>
      < / customBinding>
    < /绑定>
    <! - 变化 - >
    <服务>
      <服务名称=WCFService.Service1behaviorConfiguration =WCFService.Service1Behavior>
        <! - 服务端点 - >
        <端点地址=htt​​p://subdomain.domain.com/service1.svc绑定=customBinding合同=WCFService.IService1bindingName =Wrabind>
          <! - 
              在部署时,下面的身份元素应该被移除或更换,以反映
              身份部署的服务在其下运行。如果拆除,WCF会推断出一个合适的身份
              自动。
           - >

        < /端点>
        <端点地址=MEX绑定=mexHttpBinding合同=IMetadataExchange接口/>

      < /服务>
    < /服务>
    <行为>
      < serviceBehaviors>
        <行为NAME =WCFService.Service1Behavior>
          <! - 为了避免泄露的元数据信息,在部署之前设置以下为假的价值 - >
          < serviceMetadata httpGetEnabled =FALSE/>
          <! - 变化 - >
          <! - < serviceCredentials>
            < userNameAuthentication userNamePasswordValidationMode =自定义customUserNamePasswordValidatorType =WCFService.Authentication.DistributorValidator,WrangleCoreService/>
            < serviceCertificate findValue =WCFService的StoreLocation =LOCALMACHINESTORENAME =TrustedPeoplex509FindType =FindBySubjectName/>
          &所述; / serviceCredentials&GT  - →;
          <! - 变化 - >
          <! - 要接收故障异​​常详细信息以进行调试,设置以下为true值。设置为false部署之前,以避免泄露异常信息 - >
          < serviceDebug includeExceptionDetailInFaults =FALSE/>

        < /行为>
      < / serviceBehaviors>
    < /行为>
    < serviceHostingEnvironment>
      < baseAddress prefixFilters>
        <增加preFIX =htt​​p://subdomain.domain.com//>
      < / baseAddress prefixFilters>
    < / serviceHostingEnvironment>
    <! - < standardEndpoints>
      < webHttpEndpoint>
        < standardEndpoint NAME =helpEnabled =真
          automaticFormatSelectionEnabled =真/>
      < / webHttpEndpoint>
    &所述; / standardEndpoints&GT  - →;

  < /system.serviceModel>
 

解决方案

可以有多个原因这个错误,常见的是与服务器不验证客户端variosu原因(也许不是同一个域)。要确定确切的原因打开WCF跟踪看到它显示为红色是什么错误。你要找的是什么inenr例外,这是一个小藏在跟踪用户界面,它是在右边,中间倒树。

下面是如何设定时钟偏差:

 <安全authenticationMode =...>
           < localClientSettings maxClockSkew =0点07分00秒/>
           < localServiceSettings maxClockSkew =○时○七分00秒/>
           < secureConversationBootstrap>
              < localClientSettings maxClockSkew =00:30:00/>
              < localServiceSettings maxClockSkew =00:30:00/>
           < / secureConversationBootstrap>
< /安全>
 

请注意歪斜只能在自定义绑定来定义。由于您使用的wsHttpBinding,你需要将其转换为一个自定义的绑定,可以很容易地在网上通过 WCF做结合器

While accessing WCF service from a test client, I am getting following exception:

System.ServiceModel.Security.MessageSecurityException: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail. ---> System.ServiceModel.FaultException: An error occurred when verifying security for the message.
   --- End of inner exception stack trace ---

I searched on internet the root cause of this problem. I found that this is mostly caused due to client-server time difference. But I was unable to find the correct solution to it. Following is my server side configuration:

 <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="RequestUserName">
            <security mode="Message">
              <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" />

            </security>
        </binding>
      </wsHttpBinding>

    </bindings>
    <services>
      <service name="WCFService.Service1" behaviorConfiguration="WCFService.Service1Behavior">
        <!-- Service Endpoints -->
        <endpoint address="http://subdomain.domain.com/service1.svc" binding="wsHttpBinding" contract="WCFService.IService1" bindingName="RequestUserName">


        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFService.Service1Behavior">
          <!-- To avoid disclosing metadata information, set the value below to false before deployment -->
          <serviceMetadata httpGetEnabled="false" />

          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false" />

        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment>
      <baseAddressPrefixFilters>
        <add prefix="http://subdomain.domain.com/"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>

and Client Side Configuration:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="RequestUserName_IService1" />
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://subdomain.domain.com/service1.svc" binding="wsHttpBinding"
                bindingConfiguration="RequestUserName_IService1" contract="ServiceReference1.IService1"
                name="RequestUserName_IService1">
                <identity>
                    <userPrincipalName value="DOMAIN\subdomaincom_web" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

Anyone please help me find the solution to this problem.

UPDATE: When I traced the exception, the inner exception is showing this The security timestamp is stale because its expiration time ('2013-08-21T11:17:39.482Z') is in the past. Current time is '2013-08-21T12:31:31.897Z' and allowed clock skew is '00:05:00'.

My server uses UTC format and my client is a general purpose application that can be downloaded from any country.

UPDATE 2: Config after answer:

<system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="Wrabind">
          <transactionFlow />
          <security authenticationMode="SecureConversation" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
            <localClientSettings maxClockSkew="00:07:00" />
            <localServiceSettings maxClockSkew="00:07:00" />
            <secureConversationBootstrap messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" />
                <localClientSettings maxClockSkew="00:30:00" />
                <localServiceSettings maxClockSkew="00:30:00" />
          </security>
          <textMessageEncoding />
          <httpTransport />
        </binding>
      </customBinding>
    </bindings>
    <!-- change -->
    <services>
      <service name="WCFService.Service1" behaviorConfiguration="WCFService.Service1Behavior">
        <!-- Service Endpoints -->
        <endpoint address="http://subdomain.domain.com/service1.svc" binding="customBinding" contract="WCFService.IService1" bindingName="Wrabind">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced to reflect the 
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
              automatically.
          -->

        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFService.Service1Behavior">
          <!-- To avoid disclosing metadata information, set the value below to false before deployment -->
          <serviceMetadata httpGetEnabled="false" />
          <!-- change -->
          <!--<serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCFService.Authentication.DistributorValidator, WrangleCoreService"/>
            <serviceCertificate findValue="WCFService" storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindBySubjectName"/>
          </serviceCredentials>-->
          <!-- change -->
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false" />

        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment>
      <baseAddressPrefixFilters>
        <add prefix="http://subdomain.domain.com/"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <!--<standardEndpoints>
      <webHttpEndpoint>
        <standardEndpoint name="" helpEnabled="true"
          automaticFormatSelectionEnabled="true"/>
      </webHttpEndpoint>
    </standardEndpoints>-->

  </system.serviceModel>

解决方案

There can be multiple reasons for this error, the common one is related to server not authenticating client for variosu reasons (maybe not on the same domain). To determine the exact reasons turn on wcf trace and see what errors it shows in red. What you're looking for is the inenr exception which is a little hidden in the trace UI, it is in the right side in the middle down the tree.

Here is how to set a clock skew:

<security authenticationMode="...">
           <localClientSettings maxClockSkew="00:07:00" />
           <localServiceSettings maxClockSkew="00:07:00" />
           <secureConversationBootstrap>
              <localClientSettings maxClockSkew="00:30:00" />
              <localServiceSettings maxClockSkew="00:30:00" />
           </secureConversationBootstrap>
</security>

Note skew can only be defined on a custom binding. Since you use WSHttpBinding you need to convert it to a custom binding which can be easily be done online via WCF binding converter.

 
精彩推荐
图片推荐