Here is the situation I'm trying to deal with:
We have a WCF client that works with the http endpoint and the https endpoint, but not when redirecting (302) from http to https. We have an F5 load balancer that performs the functions of redirection and SSL, but as far as I can tell, this does not do anything unexpected for requests. Forwarding seems to be the culprit when the WCF does not want to provide Kerberos authentication information after the forwarding.
The sequence for a successful call (i.e. http without redirection) is as follows:
- Client - Sends a POST request for a service using an http scheme.
- Server - responds with unauthorized 401
- Client - sends the POST protocol with authorization
- Server - responds with 100 Continue
- Client - sending soap data and completing successfully
When the call is redirected and not completed, it looks like this:
- Client - Sends a POST request for a service using an http scheme.
- Server - returns 302 with a redirect to the https scheme for the same address
- Client - sends a GET for the https address (I canโt understand why it is GET, not POST)
- Server - responds with unauthorized 401
- The client throws an exception โThe HTTP request was not authorized using the Negotiate client authentication scheme. The authentication header received from the server wasโ Negotiate, NTLM โ.
It looks like this problem , but not quite the same (and in fact there is no answer there, although it refers to a "WCF protocol violation" that I can find documentation). If we disable the F5 redirection rule, then http and https traffic will work fine. Does WCF really not handle this simple redirect? Is there a workaround or any documentation for this flaw?
Client configuration (note that when testing with https I change TransportCredentialOnly to Transport):
<client> <endpoint address="http://fooserver/MyService.svc/" binding="basicHttpBinding" bindingConfiguration="clientBinding" contract="Contracts.IMyService" /> </client> <bindings> <basicHttpBinding> <binding name="clientBinding"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows" proxyCredentialType="Windows" /> </security> </binding> </basicHttpBinding>
Server configuration is as follows:
<system.serviceModel> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> <services> <service behaviorConfiguration="MyServiceBehavior" name="MyService"> <endpoint address="" binding="basicHttpBinding" bindingConfiguration="securedBinding" contract="Contracts.IMyService"> </endpoint> </service> </services> <bindings> <basicHttpBinding> <binding name="securedBinding"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows" proxyCredentialType="Windows"/> </security> </binding> </basicHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="MyServiceBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="true"/> <useRequestHeadersForMetadataAddress> <defaultPorts> <add scheme="http" port="80" /> <add scheme="https" port="443" /> </defaultPorts> </useRequestHeadersForMetadataAddress> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
source share