WCF service: The HTTP request is unauthorized with client authentication scheme 'Negotiate' - wcf

I have a WCF client in a VS2012 project that has the configuration:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="myServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="myServiceBehaviour"
name="xxx.Web.Mvc.Client.Services.MyService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding" name="BasicHttpEndpoint" contract="xxx.Wcf.IMyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
Within IIS 7.5, the service is set to use Windows authentication.
I'm using basicHttpBinding over HTTPS. My requirements are SSL, but I've ended up using Windows authentication to get it to work.
I have a quick and dirty console application with the following config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpoint">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://dev.xxxx.local/xxxx.Web.Mvc.Client/services/MyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpoint"
contract="MyService.IMyService" name="BasicHttpEndpoint" />
</client>
</system.serviceModel>
This works fine, like a dream.
The same configuration (I thought) in a VB application:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpoint" sendTimeout="10:00:00"> <!-- See point 1 below -->
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://xxxx.inter.local/xxxx.Web.Mvc.Client/services/MyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpoint"
contract="MyService.IMyService" name="BasicHttpEndpoint" />
</client>
Doesn't work, instead I get:
MessageSecurityException: The HTTP request is unauthorized with client
authentication scheme 'Negotiate'. The authentication header received
from the server was 'Negotiate
oXIwcKADCg....igAwIBAaERMA8bDWlvbXZuZWRkZXYwMiQ='.
The service is clearly fine, it's just the client (and specifically the web site client) that is struggling.
Seemingly, the server is rejecting the authorisation from the web site client. The Negotiate response includes the token, I've ommitted for obvious reasons here, but you can see the structure.
How can I get this working? With the only requirement being it needs to be over SSL. I'd prefer to send credentials, but I'm not bothered. I didn't get very far using anonymous, anyway.
Points:
The sendTimeout setting is applied because for some reason when being called remotely from the web site client, execution takes over 1 minute and times out.

by this: http://blogs.msmvps.com/alvin/2008/11/14/net-3-5-sp1-breaking-change-to-wcf/
you may need to add this block to your endpoint-identity node
<servicePrincipalName value=""/>
turning it to:
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding" name="BasicHttpEndpoint" contract="xxx.Wcf.IMyService">
<identity>
<dns value="localhost" />
<servicePrincipalName value=""/>
</identity>
</endpoint>

Related

Calling Action: ContractFilter mismatch at the EndpointDispatcher

I'm looking on this issue for hours. I try to get a WCF service running and now it comes down to a ContractFilter-Mismatch-Error wit the Action "http://tempuri.org/ISystemService/LogIn". Here is the relevant part of the client config:
<bindings>
<netTcpBinding>
<binding name="netTcpBindingConfig_TimeRegistrationSystemService" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
<binding name="netTcpBindingConfig_SystemService" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://mysrv.myteam.local:54520/MyCompany.Services.TimeRegistrationSystemService.svc" binding="netTcpBinding" bindingConfiguration="netTcpBindingConfig_SystemService" contract="SystemService.ISystemService" name="NetTcpBindingBinding_ISystemService" />
<endpoint address="net.tcp://mysrv.myteam.local:54520/MyCompany.Services.SystemService.svc" binding="netTcpBinding" bindingConfiguration="netTcpBindingConfig_TimeRegistrationSystemService" contract="TimeRegistrationSystemService.ITimeRegistrationSystemService" name="NetTcpBindingBinding_ITimeRegistrationSystemService" />
</client>
and here the server's config - binding configuration:
<bindings>
<netTcpBinding>
<binding name="netTcpBindingConfig_OtherInterfaceService">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
<binding name="netTcpBindingConfig_TimeRegistrationSystemService" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
<binding name="netTcpBindingConfig_SystemService" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
server's config - services:
<service name="MyCompany.Services.EasyLogicInterfaceService" behaviorConfiguration="release">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="netTcpBindingConfig_EasyLogicInterfaceService" contract="MyCompany.Services.IEasyLogicInterfaceService">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://mysrv.myteam.local:54520/MyCompany.Services.EasyLogicInterfaceService.svc/" />
</baseAddresses>
</host>
</service>
<service name="MyCompany.Services.TimeRegistrationSystemService" behaviorConfiguration="release">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="netTcpBindingConfig_TimeRegistrationSystemService" contract="MyCompany.Services.ITimeRegistrationSystemService">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://mysrv.myteam.local:54520/MyCompany.Services.SystemService.svc/" />
</baseAddresses>
</host>
</service>
<service name="MyCompany.Services.SystemService" behaviorConfiguration="release">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="netTcpBindingConfig_SystemService" contract="MyCompany.Services.ISystemService">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://mysrv.myteam.local:54520/MyCompany.Services.SystemService.svc/" />
</baseAddresses>
</host>
</service>
and the behaviors:
<serviceBehaviors>
<behavior name = "debug">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name = "release">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
I first thought it might be a typo but I don't find it (am I blind?!?). I already updated my service references in the client solution and published both, the server code and the client code, afterwards. And also, I already put all relevant strings in the client config from the server config (binding configuration, endpoint addesses etc.) by copy'n'paste to avoid a typo.
Than I run through a lot of answers here on stackoverflow without finding any solving my problem.
I can run the client and the server code locally without problems. The problems occur only after deployment.
Tracking the call by system.diagnostics doesn't reveal something else than this error message.
Do you see more than I do or do you know any issues wich triggers this errors? When this error comes up, a connection between the client and the server already is succesfully established, right? So it cannot be a problem with Kerberos or something...
I apologize in advance if it turns out that it really is just a typo. But I don't find any...
Best regards!
<client>
<endpoint address="net.tcp://mysrv.myteam.local:54520/MyCompany.Services.TimeRegistrationSystemService.svc"... contract="SystemService.ISystemService" name="NetTcpBindingBinding_ISystemService" />
<endpoint address="net.tcp://mysrv.myteam.local:54520/MyCompany.Services.SystemService.svc"... contract="TimeRegistrationSystemService.ITimeRegistrationSystemService" name="NetTcpBindingBinding_ITimeRegistrationSystemService" />
</client>
The client config endpoints have reverse contract.
As per your service.config, For the TimeRegistrationSystemService.svc the contract should be ITimeRegistrationSystemService and for SystemService.svc the contract should be ISystemService.

WCF Service hosted in Windows Service stops responding

Our WCF service is hosted in a Windows Service using net tcp binding with port 8090.
It works well for the most part, but from time to time, client applications fail to connect to the service, even if the service is still running and there are no apparent errors in the event log. The client application will get the following exception while connecting:
The open operation did not complete within the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout.
The client machine is still able to ping the server.
Restarting the windows service solves the problem, but users don't like it.
Any idea what could be happening here? I've read about the Net TCP Listener service and making sure the server has been patched. But I think that's only for net tcp binding hosted in IIS, and might not be applicable in my case.
Thanks!
Here's the service configuration:
<services>
<service behaviorConfiguration="behavior1" name="Tamer.Service.WcfService">
<endpoint binding="netTcpBinding" bindingConfiguration="netTcpLarge" name="endpoint1" contract="Tamer.Service.Library.IFundService" />
<endpoint binding="netTcpBinding" bindingConfiguration="netTcpLarge" name="endpoint2" contract="Tamer.Service.Library.IEntitlementService" />
<endpoint binding="netTcpBinding" bindingConfiguration="netTcpLarge" name="endpoint3" contract="Tamer.Service.Library.IReferenceDataService" />
<endpoint binding="netTcpBinding" bindingConfiguration="netTcpLarge" name="endpoint4" contract="Tamer.Service.Library.ITransactionService" />
<endpoint binding="netTcpBinding" bindingConfiguration="netTcpLarge" name="endpoint4" contract="Tamer.Service.Library.IDocumentService" />
<endpoint binding="netTcpBinding" bindingConfiguration="netTcpLarge" name="endpoint5" contract="Tamer.Service.Library.IFileStreaming" />
<endpoint binding="netTcpBinding" bindingConfiguration="netTcpLarge" name="endpoint6" contract="Tamer.Service.Library.IReportService" />
<endpoint address="net.tcp://localhost:8091/mex" binding="mexTcpBinding" name="mex" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="behavior1">
<serviceMetadata policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceThrottling maxConcurrentCalls="192" maxConcurrentSessions="192" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="netTcpLarge" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="01:00:00" sendTimeout="01:00:00" maxBufferPoolSize="524288"
maxReceivedMessageSize="2147483647" maxConnections="192" listenBacklog="100">
<!--listenBacklog="100"-->
<readerQuotas maxDepth="32"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="None">
<message clientCredentialType="None"/>
<transport protectionLevel="None" clientCredentialType="None"/>
</security>
<!--reliableSession enabled="false"/-->
</binding>
</netTcpBinding>
</bindings>

Accessing to a wcf service

i have a problem.
I tried to access to the wcf web service from an application ASP.net MVC, I got this exception when I am calling the method.
There was no endpoint listening at the URI that could accept the
message. This is often caused by an incorrect address or SOAP action.
See InnerException, if present, for more details.
this is my code
var client = new DSServiceClient();
client.Methode();
service model section of web.config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IDSService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="localhost:1695/Service1.svc"; binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDSService" contract="ServiceReference1.IDSService" name="BasicHttpBinding_IDSService" />
</client>
</system.serviceModel>
Check that the URL you are using is accessible from asp.net mvc site. If you are using http binding you can copy and paste url into browser on the server where your site is deployed. The URL should be in web.config file in the root folder of your site.
Are you using IIS 7 to host? If So you can go to your site, enable directory browsing (temporarily), click on the browse link on the right side of IIS manager, select the service class ("something.svc") and it should pop up in a browser. At that point you can copy the URL from the browser and replace localhost with the server name. You can even go on to click on the top link on that page to get to the WSDL. If there is a problem you may get an error message that may be more helpful.
this is my web.config of the service
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="DSWebService.Service1Behavior"
name="DSWebService.Service1">
<endpoint address="" binding="wsHttpBinding"
contract="DSWebService.IDSService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:1695/DSWebService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DSWebService.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- 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>
and this is my web.config of the client:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IDSService" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:1695/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IDSService" contract="IDSService"
name="WSHttpBinding_IDSService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
and the 2 project should be on the same solution and after we do add reference :
DSServiceClient client = new DSServiceClient();
client.Methode();

Accessing WCF service on AppHarbor via https

I'm trying to secure my WCF service using transport security model. I've successfully deployed my service to AppHarbor. But I'm getting the following exception when I try to access service page:
[InvalidOperationException: Could not find a base address that matches scheme https for the endpoint with binding BasicHttpBinding. Registered base address schemes are [http].] ...
I haven't uploaded any certificates, just using piggyback SSL there. I've downloaded the build and deployed it on my machine. It works fine.
Here is my system.serviceModel section of web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="AuthService.AuthServiceBehavior" name="AuthService.AuthService">
<host>
<baseAddresses>
<add baseAddress="https://auth.apphb.com/AuthService.svc" />
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="TransportSecurity" contract="AuthService.IAuthService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="AuthService.AuthServiceBehavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I've already tried this Hosting a WCF Web API app on AppHarbor?
Can somebody please explain me what I'm doing wrong?
This issue frequently appear when you communicate with the wcf web service thru the LB (AppHarbor one of the example of it).
You should know several things about such kind of communications.
1) Communication between yours client application and LB is secured (https is in use). So you should leverage security binding on the client side.
<basicHttpBinding>
<binding name="BasicHttpBinding_IAuthService">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
2) Communication between LB and web-front uses http, so server binding should be basicHttpBinding without extra configuration.
<endpoint binding="basicHttpBinding" contract="AuthService.IAuthService" />
Summarizing all that stuff we have
Client
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IAuthService">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://auth.apphb.com/AuthService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAuthService"
contract="AuthService.IAuthService" name="BasicHttpBinding_IAuthService" />
</client>
</system.serviceModel>
</configuration>
Server
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<protocolMapping>
<add scheme="http" binding="basicHttpBinding" />
</protocolMapping>
<bindings>
<basicHttpBinding/>
</bindings>
<services>
<service behaviorConfiguration="AuthService.AuthServiceBehavior" name="AuthService.AuthService">
<endpoint binding="basicHttpBinding" contract="AuthService.IAuthService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="AuthService.AuthServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Your approach is not going to work right off the bat. This is because SSL is terminated at the load balancers and the app servers see http traffic. You can read more about AppHarbor load balancers here.
You might be able to fool WCF with this module.
There are also some hints in this discussion: http://support.appharbor.com/discussions/problems/829-transportwithmessagecredential-https-ssl

Calling an HTTPS WCF service with Anonymous authentication?

Even though anonymous access is enabled on the Virtual Directory of the WCF service and Integrated Authentication is disabled, I still get the error:
The HTTP request is unauthorized with client authentication scheme
'Anonymous'. The authentication header received from the server was
'Negotiate,NTLM'.
This is what the security definition on client binding configuration looks like:
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="None" negotiateServiceCredential="false" />
</security>
And the endpoint definition:
<endpoint address="https://url.com/Service.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService"
contract="IService" name="WSHttpBinding_IService">
<identity>
<servicePrincipalName value="spn" />
</identity>
</endpoint>
I've already tried adding:
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
But it doesn't seem to have any effect.
Is there something on IIS that I need to change?
[EDIT]
Service configuration:
<behaviors>
<endpointBehaviors>
<behavior name="defaultBehavior"/>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="metadataSupport">
<serviceMetadata httpsGetEnabled="true" httpsGetUrl=""/>
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="https" port="443" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="ServiceLibrary.Service"
behaviorConfiguration="metadataSupport">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="wsSecureBinding"
contract="ServiceLibrary.IService"/>
<endpoint address="mex"
binding="wsHttpBinding"
bindingConfiguration="wsSecureBinding"
name="mexHttps"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="wsSecureBinding">
<security mode="Transport"/>
</binding>
</wsHttpBinding>
</bindings>
Modify your binding configuration in service to:
<bindings>
<wsHttpBinding>
<binding name="wsSecureBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
It expects Windows credentials by default.