Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make WCF service server-client time difference independent?

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>
like image 479
Aishwarya Shiva Avatar asked Aug 23 '13 10:08

Aishwarya Shiva


People also ask

What is the need for activation or hosting of a WCF service?

Hosting a WCF service in Windows Activation Service (WAS) is most advantageous because of its features such as process recycling, idle time management, common configuration system, and support for HTTP, TCP, etc.

Where can a WCF service be hosted?

There are three types of hosting environments for WCF services: IIS, WAS, and self-hosting. The term “self-hosting” refers to any application that provides its own code to initialize the hosting environment. This includes console, Windows Forms, WPF, and managed Windows services.


1 Answers

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.

like image 170
Yaron Naveh Avatar answered Nov 08 '22 12:11

Yaron Naveh