WCF Windows authentication not working with wsHttpBinding - c#

Problem is that I cannot get windows authentication working with the wsHttpBinding.
This is the config:
<services>
<service name="WcfService1.Service1">
<endpoint address="" bindingConfiguration="testbinding" contract="WcfService1.IService1" binding="wsHttpBinding"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="testbinding">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
This is the response from the server when trying to call a method:
The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate oXMwcaADCgEBomoEaGBmBgkqhkiG9xIBAgIDAH5XMFWgAwIBBaEDAgEepBEYDzIwMTcwODE2MjA1MjQwWqUFAgMK8G2mAwIBKakOGwxDT1JQLlNBQUIuU0WqGjAYoAMCAQGhETAPGw1jb3JwYXBwbDU5ODgk'.
Also there is a inner exception saying:
"The target principal name is incorrect"
I have setup a new site in IIS fresh for testing purposes with windows authentication enabled and Everything else disabled(I am not doing any ASP impersonation/double hop). Providers for windows authentication is Negotiate,Ntlm. Kernel mode authentication is enabled.
The application pool is running with a Active Directory service account.
The goal in the end is to use Kerberos for authentication but since it doesn't even work with Ntlm I have not started with the SPN and that stuff to get kerberos working yet.
It does however work if I change the application pool to be run with "ApplicationPoolIdentity" and not a AD service account?
I must have the app pool running with the AD service account.
If I change the config to:
<services>
<service name="WcfService1.Service1">
<endpoint address="" bindingConfiguration="hbinding" contract="WcfService1.IService1" binding="basicHttpsBinding"/>
</service>
</services>
<bindings>
<basicHttpsBinding>
<binding name="hbinding">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpsBinding>
It works fine(keeping the AD service account as well), why is that?
I dont wanna use basicHttpsBinding
I see a difference in the client config file (using the wcftestclient) that when using wshttp it has:
<identity>
<userPrincipalName value="serviceaccount#contoso.com" />
</identity>
Does it have something to do with this? (Just guessing wildly here)
The endpoint is https,IIS 8 on Windows Server 2012R2.

A lot of it depends on how is your domain set up, but you might try different type of Client credential type:
<services>
<service name="WcfService1.Service1">
<endpoint address="" bindingConfiguration="testbinding" contract="WcfService1.IService1" binding="wsHttpBinding"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="testbinding">
<security mode="Transport">
<transport clientCredentialType="Ntlm"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
Also, with wsHttpBinding there is negotiation that takes place behind the scene. Because the guidance on that negotiation is not specifically defined it makes sense sometimes to turn it off:
<services>
<service name="WcfService1.Service1">
<endpoint address="" bindingConfiguration="testbinding" contract="WcfService1.IService1" binding="wsHttpBinding"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="testbinding">
<security mode="Transport">
<message negotiateServiceCredential="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
A Kerberos domain must exist for it to work.

On the client side the generated identity tag was causing the issue
<identity>
<userPrincipalName value="serviceaccount#contoso.com" />
</identity>
If i clear the value it works fine.
So i cleared that value in the web.config.
I can now setup kerberos and it works fine as well, gonna try setting the servicePrincipalName tag as well.

Related

The endpoint at 'http://Foo' does not have a Binding with the None MessageVersion

This project working perfectly at my local pc but when I run at server I am getting this error.
The endpoint at 'http://Foo' does not have a Binding with the None
MessageVersion. 'System.ServiceModel.Description.WebHttpBehavior' is
only intended for use with WebHttpBinding or similar bindings.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BIServicesSoap" maxBufferPoolSize="20000000" maxBufferSize="20000000"
maxReceivedMessageSize="20000000" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://FooA"
binding="basicHttpBinding" bindingConfiguration="BIServicesSoap"
contract="FinansService.BIServicesSoap" name="BIServicesSoap" />
<endpoint address="http://FooB"
binding="basicHttpBinding" bindingConfiguration="BIServicesSoap"
contract="FinansNet.BIServicesSoap" name="BIServicesSoap1" />
</client>
</system.serviceModel>
Note: At server there is another WCF project runs and my project runs under a sub folder. could web configs mix?

Error With service endpoint in wcf https ssl. Cannot find base address that matches scheme http for the end point with binding WebHttpBinding

i have the following code in my server
<services>
<service name="ME.Streets.WebGateway.DuplexService.DuplexService"
behaviorConfiguration="sb">
....
<endpoint
address=""
binding="webHttpBinding"
behaviorConfiguration="webHttpEndpointBehavior"
contract="ME.Streets.WebGateway.DuplexService.Interface.IPolicyRetriever"/>
....
<host>
<baseAddresses>
<add baseAddress="https://localhost:10201" />
</baseAddresses>
</host>
</service>
I have been switching the silverlight application over to HTTPS with SSL and WCF, but if i run my server, i recieved the following error
- System.InvalidOperationException: Could not find a base address that matches
scheme http for the endpoint with binding WebHttpBinding. Registered base address
schemes are [https].
I am highly unsure of where this error is coming from. Do i have to install a https <baseaddress> node within the <service> node?
Fixed!
Changed the endpoint to this (added bindingConfiguration="webHttpsBinding"):
<services> .....
<endpoint
address=""
binding="webHttpBinding"
behaviorConfiguration="webHttpEndpointBehavior"
bindingConfiguration="webHttpsBinding"
contract="ME.Streets.WebGateway.DuplexService.Interface.IPolicyRetriever">
</endpoint>
......
</services>
And the new binding configuration is as follows:
<bindings>....
<webHttpBinding>
<binding name="webHttpsBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
......
</bindings>
This gives the end point a binding to a http binding that specifies which was to transport the information and the type of credentials that connected users must have

Configure WCF Client to consume a WCF Service using HTTP GET

I have a WCF Service which allows only HTTP GET requests:
[WebInvoke(Method="GET", ResponseFormat=WebMessageFormat.Json)]
public string GetAppData()
The service is exposed using webHttpBinding
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="AppSvcBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
I have my client whose config looks like
<system.serviceModel>
<client>
<endpoint address="http://localhost/AppService/Service.svc"
binding="webHttpBinding"
bindingConfiguration="webHttpBindingConfig"
contract="AppSvc.IService"
behaviorConfiguration="AppSvcBehavior"
name="AppSvcClient">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</client>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingConfig">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="AppSvcBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
My client code is a simple
ServiceClient client = new ServiceClient("AppSvcClient");
String result = client.GetAppData();
On executing this code I get the error:
The remote server returned an unexpected response: (405) Method Not Allowed.
I checked with fiddler and found that my client is sending a POST message whereas the service expects a GET hence the error.
I wish to know how to configure the client so that is sends GET request to the service.
Use WebGet instead of WebInvoke
Edit
Start by changing your method to this:
[WebInvoke(Method="GET", ResponseFormat=WebMessageFormat.Json,UriTemplate = "/")]
public string GetAppData()
Make sure that webhttpbinding is specified on the server side.
This fixes it on the server side.
Take a backup of your client code.
On the client side delete the service reference. Make sure that all config is removed.
Then add the service reference again. Now it shoud be OK.
I had a similar problem where the generated proxy service interface on the client was missing the WebGet attribute on my methods.
I added the attribute manually and it resolved the problem.
So it seems like the best current solution is to extract the service interfaces into a separate assembly and then share this assembly between the server and its clients.
The automatic proxy generator seems to be buggy.

baseAddresses supplied to ServiceHost are not Https

I am trying to configure my WCF Service to be HTTPS. I have configured the behaviors and the services with the relevant addresses but I cannot understand why the address which is supplied to the service host is still http.
The behavior I am using is here:
<behavior name="RequestProcessorBehavior">
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="ServiceAuthentication,Services"/>
</serviceCredentials>
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceThrottling maxConcurrentCalls="500" maxConcurrentInstances="500"/>
</behavior>
The service element is here
<service name="MyNamespace.WcfRequestProcessor" behaviorConfiguration="RequestProcessorBehavior">
<host>
<baseAddresses>
<add baseAddress="https://xxxxxxxxxxxxxx/Services/"/>
</baseAddresses>
</host>
<!--
Use the listenUri attribute if this causes a problem with the load balancer.
The url of the listenUri should be that of the load balancer
-->
<endpoint address=""
bindingNamespace="https://xxxxxxxxxxxxxx/Services/"
contract="MyNamespace.IWcfRequestProcessor"
binding="basicHttpBinding"
bindingConfiguration="RequestProcessorBinding">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="wsHttpBinding"
bindingNamespace="https://xxxxxxxxxxxxxx/Services/"
contract="MyNamespace.IWcfRequestProcessor"
binding="wsHttpBinding"
bindingConfiguration="wsBinding">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
When I add a breakpoint onto the constructor of the ServiceHost I can see that the baseAddresses parameter contains only one address and that is http and not https. When i try to visit the svc page I get the following error and I can see why it would show that but I cannot see what I can change to make the baseAddress which gets passed to the ServiceHost constructor https and not http.
Could not find a base address that
matches scheme https for the endpoint
with binding BasicHttpBinding.
Registered base address schemes are
[http].
Any help would be greatly appreciated.
UPDATE #1
The binding configuration section which I left out of the original question:
<bindings>
<basicHttpBinding>
<binding name="RequestProcessorBinding" maxReceivedMessageSize="2147483647" receiveTimeout="00:30:00" sendTimeout="00:30:00">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"/>
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
This is currently inside a development environment and in IIS6. This is inside the Default Website.
Are you running on IIS or self hosted? If it's IIS, you need to have IIS configured correctly for SSL. Also, you don't mention what your binding configuration looks like, but it needs to be set to enable transport security as well.

Authentication failed between client and WCF service

This a question that already has been discussed a couple of times on SO but I couldn't find any suitable solution to my problem. I have a WCF service hosted on an external server (other domain) and I'm trying to consume it from a command line application. I receive the following error:
The request for security token could not be satisfied because authentication failed.
The service is configured inside a web.config file:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding_IRun">
<security mode="None">
<message clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://www.domain.net"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior name="calculadora.SOA.RunBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="calculadora.SOA.RunBehavior" name="calculadora.SOA.Run">
<endpoint address="http://www.domain.net/calculadora/SOA/run.svc" binding="wsHttpBinding" contract="calculadora.SOA.IRun">
<identity>
<dns value="domain.net"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
On the client side, I create a custom binding to connect to the service. Here is the security configuration:
standardBinding.Security.Mode = SecurityMode.None;
standardBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
standardBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
standardBinding.Security.Transport.Realm = "";
standardBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
standardBinding.Security.Message.NegotiateServiceCredential = false;
standardBinding.Security.Message.EstablishSecurityContext = false;
standardBinding.Security.Message.AlgorithmSuite = SecurityAlgorithmSuite.Default;
I'm not using any security mechanism for authentification but still, the service seems to be expecting one. When working on different domains, is it mandatory to use a basic authentification?
EDIT: I wasn't referencing any binding configuration at my endpoint. Once the reference was set, I received another message error:
{"The message with Action 'http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue' cannot be processed at the
receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract
mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the
receiver. Check that sender and receiver have the same contract and the same binding (including security
requirements, e.g. Message, Transport, None)."}
The issue was caused by my client's binding. While I was creating my custom binding using the standard 'WSHttpBinding', the 'SecurityMode' property was set to 'Message' instead of 'None'. Now the code looks like the following and the service finally works:
WSHttpBinding standardBinding = new WSHttpBinding(SecurityMode.None, false);
CustomBinding myCustomBinding = new CustomBinding(standardBinding);
Many thanks to marc_s!
I think the problem is your service endpoint definition:
<endpoint address="http://www.domain.net/calculadora/SOA/run.svc"
binding="wsHttpBinding" contract="calculadora.SOA.IRun">
You are using the standard wsHttpBinding - which defaults to integrated Windows security as message security.
While you do define a binding configuration (called wsHttpBinding_IRun), you're not referencing it in your endpoint definition - thus it doesn't come into play. You need to extend your service endpoint definition with a bindingConfiguration attribute like so:
<endpoint address="http://www.domain.net/calculadora/SOA/run.svc"
binding="wsHttpBinding"
bindingConfiguration="wsHttpBinding_IRun"
contract="calculadora.SOA.IRun">
in order to actually use your defined binding configuration (including the security settings).
I ran into the same issue and after a whole day invested, finally I figure out how to fix. The key is put establishSecurityContext="false" into message tag.
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" establishSecurityContext="false" />
</security>

Categories