2

Some background:

We're migrating a fairly complex web-serviced architecture to newer Windows servers. Some web sites/services have been moved from IIS6 to IIS7 as part of this. So new machine, same configuration, possibly different version of IIS.

All code has been recompiled (unchanged) into VS2012/.NET 4.0. This is a mix of C# and VB.NET.

We have a WCF web service with the following configuration.

<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<extensions>
  <behaviorExtensions>
    <add name="caller" type="xxx.CallerBehaviorExtensionElement, xxx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  </behaviorExtensions>
</extensions>
<behaviors>
  <endpointBehaviors>
    <behavior name="caller">
      <caller />
    </behavior>
 <clientCredentials>
  <serviceCertificate>
   <authentication revocationMode="NoCheck" />
  </serviceCertificate>
  <windows allowedImpersonationLevel="Delegation" />
 </clientCredentials>
</behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="xxxWcfBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<services>
  <service behaviorConfiguration="xxxWcfBehavior" name="xxxWcf">
    <endpoint address="" behaviorConfiguration="caller" binding="wsHttpBinding" contract="xxxWcf">
      <identity>
        <dns value="localhost" />           
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>

Calling this from ASMX web service (1) works fine. Calling this from ASMX web service (2) does not work, returning the following exception:

System.ServiceModel.Security.SecurityNegotiationException: The caller was not authenticated by the service. ---> System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed.

This is the client's web.config:

 <system.serviceModel>
  <extensions>
    <behaviorExtensions>
      <add name="caller" type="xxxx.CallerBehaviorExtensionElement, xxx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
    </behaviorExtensions>
  </extensions>
  <behaviors>
    <endpointBehaviors>
      <behavior name="caller">
        <caller />
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <bindings>
    <wsHttpBinding>
      <binding name="xxxDataWcf" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
        <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
        <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
        <security mode="Message">
          <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
          <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true"/>
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
    <client>
        <endpoint address="http://xxxDataWcf.svc"
            binding="wsHttpBinding" bindingConfiguration="xxxDataWcf"
            contract="xxxDataWcf" name="xxxDataWcf">
            <identity>
                <dns value="localhost" />
            </identity>
        </endpoint>

    </client>
</system.serviceModel>

But what is the difference between (1) and (2)? I would suggest nothing. Multiple people have compared IIS configurations (this occurs across v6 and v7), compared web.configs, created test projects and compared permissions.

I've been torn whether to include the CallerBehaviorExtensionElement or not. I'm sure that it isn't relevant but have included it because removing it would invalidate the configuration to the point of being unhelpful. All this is is a cheat to pass the username across the hops without relying on delegation/ASP.NET authentication. To be clear, this does not form authorisation nor does it interact with Windows' authorisation infrastructure in any way. We just use it to mark the eventual record with the caller's username.

Based on our previous investigations:

It seems the stock response for the error is to weaken security, which we are loathe to do. This worked fine in an IIS6 configuration and works fine on a local development machine under IIS7 (bizarrely, even across machine/OS boundaries). So it works in principle.

We're hitting our heads and look to the community for a hint. If there is any specific information you need, please ask. This is WCF and I'm sure you'll appreciate that the configuration can be very noisy.

Community
  • 1
  • 1
Program.X
  • 7,250
  • 12
  • 49
  • 83
  • Can you clarify a couple of things? Are both the client ASMX and server WCF services deployed on same machine? Or do you mean to say that the WCF service is unchanged in its server and you only migrated the ASMX client to a different server? Can't seem to fully grasp what was migrated and where :) – tomasr Dec 19 '14 at 17:58
  • Appreciate the confusion, we're so deep into this we're struggling ourselves. In the case of the non-working scenario, all services are on the same machine, which fails with the quoted error. Running from Visual Studio on a development machine targeting the WCF service at the server does work. – Program.X Dec 19 '14 at 20:35

1 Answers1

2

Based on your last comment, I think it's very, very likely you're suffering from the issue described here: http://blogs.msdn.com/b/distributedservices/archive/2009/11/10/wcf-calling-wcf-service-hosted-in-iis-on-the-same-machine-as-client-throws-an-authentication-error.aspx

tomasr
  • 13,683
  • 3
  • 38
  • 30
  • 1
    Whilst technically not the answer it did point us to the cause, so many thanks for that. The issue was for WCF services accessed using FQDNs on the same machine. Upon following Method 2 in the linked document we were able to find the cause. As part of the migration which this problem was a part of we're migrating between domains and the decision was made to use FQDNs to document endpoints, which introduced the issue. I'll thus mark it as an answer to help others, who hopefully will read this comment too! – Program.X Dec 22 '14 at 11:43