Calling an HTTPS WCF service with Anonymous authentication? - wcf

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.

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: The HTTP request is unauthorized with client authentication scheme 'Negotiate'

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>

Forcing WCF to use HTTPS

How do I ensure my WCF service is over HTTPS and all communication is over HTTPS?
Theres nothing in my web.config file of the service that says http://... or https://....
HTTPS is set up in IIS and I can access the web service via http and https.
Or is this not required if it's encrypted anyway with message level security?
<bindings>
<wsHttpBinding>
<binding name="Binding1" maxReceivedMessageSize="20000000">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
HTTPS is HTTP over Transport-Layer Security (TLS). To enable it, you need to configure your binding to use transport security in addition to the existing message-level security:
<bindings>
<wsHttpBinding>
<binding name="Binding1" maxReceivedMessageSize="20000000">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
here is config for https:
<services>
<service name="WcfTransport.Service1" behaviorConfiguration="MyHttpsBehaviour">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="TransportSecurityBinding" contract="WcfTransport.IService1"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors >
<behavior name="MyHttpsBehaviour" >
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="TransportSecurityBinding">
<security mode="Transport">
<transport clientCredentialType="Windows"></transport>
</security>
</binding>
</wsHttpBinding>
</bindings>
note that httpsGetEnabled is set to true and httpGetEnabled is set to false. You can also remove mex endpoint if you don't need metadata exchange.
p.s. Message security is for message encryption, but of course, you can use message security with https.

securing a wcf with https

I hosted a WCF .svc file in IIS 6.0 under a virtual directory secured with https. When requesting the wsdl through my browser I get a http 400 error. Here's a chunk of my web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="TransportSecurity">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="AuthWorkStation_Extranet.App_Code.AwsService" behaviorConfiguration="ServiceBehavior">
<endpoint name="" address="https://extlpo01.srr.fr/Sphinx/Service.svc" binding="basicHttpBinding" bindingConfiguration="TransportSecurity" contract="AuthWorkStation_Extranet.App_Code.IAwsService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceCredentials>
<serviceCertificate storeName="Root" findValue="CA_SRR_DISTRIB" x509FindType="FindBySubjectName" />
</serviceCredentials>
<serviceMetadata httpsGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
anyone knows what's wrong with my setup ?
If you just want HTTPS, you need to update your web.config. Change the following:
<bindings>
<basicHttpBinding>
<binding name="TransportSecurity">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
To:
<bindings>
<basicHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>

WCF Streaming on service with Windows Authentication Endpoint

I have a WCF service with two endpoints defined by the configuration file below:
<system.serviceModel>
<services>
<service name="SyncService" behaviorConfiguration="SyncServiceBehavior">
<endpoint name="Data" address="Data" binding="basicHttpBinding" bindingConfiguration="windowsAuthentication" contract="ISyncService"/>
<endpoint name="File" address="File" binding="basicHttpBinding" bindingConfiguration="httpLargeMessageStream" contract="ISyncService"/>
<endpoint address="mex" binding="webHttpBinding" bindingConfiguration="windowsAuthentication" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="httpLargeMessageStream" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" transferMode="Streamed" messageEncoding="Mtom" />
<binding name="windowsAuthentication" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm=""></transport>
<message algorithmSuite="Default" clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="windowsAuthentication">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"></transport>
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="SyncServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"></serviceHostingEnvironment>
</system.serviceModel>
I want to use windows authentication for the Data endpoint, but have recently discovered that you cannot use windows authentication for streaming over HTTP. I removed the security element for the File endpoint, but still get the following error:
HTTP request streaming cannot be used in conjunction with HTTP
authentication. Either disable request streaming or specify anonymous
HTTP authentication. Parameter name: bindingElement
Is it possible to have two endpoints on the same service use different authentication methods like this? Why can't I use windows authentication for streaming?
I have also tried what was suggested in this thread, but to no avail:
Which authentication mode of basichhtpbinding can be used to secure a WCF Service using Streaming?
Unfortunately this is not supported.