WCF with windows authentication problems - c#

I am building wcf aplication that will work only with users that have User+Password to the windows where this wcf is located.That mean is my wcf located on server X and i call function GetData(5) i will see the logon form (the same users that in windows) and entered User+Password and then get data back, my main goal is to pass User+Password to avoid this logon window,but now i can't forse my wcf to ask for windows authentication,it is returning data to everyone.
What i am doing wrong?
I am using Vs2012(4.5)
P.s if any one have example of wcf that use windows authentication i
will be very happy to see it.
My webConfig
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<authentication mode="Windows" />
<identity impersonate="false" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="WcfService10.Service1">
<endpoint address="WCF10" binding="basicHttpBinding" bindingConfiguration="NewBinding10"
contract="WcfService10.IService1" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="NewBinding10">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Windows" customUserNamePasswordValidatorType="Type, Assembly" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>

To pass alternative windows credentials to a service, use the following code:
var proxy = new MyServiceClient();
proxy.ClientCredentials.Windows.ClientCredential.Domain = "MyDomain";
proxy.ClientCredentials.Windows.ClientCredential.UserName = "MyUsername";
proxy.ClientCredentials.Windows.ClientCredential.Password = "MyPassword";
proxy.DoSomething();
proxy.Close();

Here one config with webHttpBinding and Windows Transport security. You have to change the service name, baseAddress, contract="Server.IServicemame"
<system.serviceModel>
<!--Services-->
<services>
<service name="Server.servicemame">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9011/servicemame/service"/>
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="Server.IServicemame" bindingConfiguration="HttpBindingWithSecurity">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<!--Behaviors-->
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization impersonateCallerForAllOperations="false" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceCredentials>
<windowsAuthentication allowAnonymousLogons="false"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<!--Bindings-->
<bindings>
<webHttpBinding>
<binding name="HttpBindingWithSecurity">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>

Related

WCF service - could not retrieve the service binding

We have a simple IIS service just hosting one method via https. The service can be consumed and used w/ SOAPUI and it connects and works just fine. However, we have a client on another network who's consuming our IIS service endpoint and trying to use the service, but the client server is reporting an error:
Could not retrieve the Service Binding
I have no idea what this means exactly and why it works just fine through another network, but fails on another. Does anyone know what I might chase down to solve this error on the failing server. Maybe there's something I need to change in the service, not sure. Thanks.
Here is my web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
</appSettings>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding_eLink" maxReceivedMessageSize="20000000">
<security mode="Transport" >
<transport clientCredentialType= "None" />
</security>
</binding>
</basicHttpBinding>
<mexHttpsBinding>
<binding name="secureMexBinding" />
</mexHttpsBinding>
</bindings>
<client>
</client>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="eLink.PublishActionWebService">
<endpoint
address=""
binding="basicHttpBinding"
bindingConfiguration="basicHttpBinding_eLink"
contract="eLink.IService"/>
<endpoint
address="mex"
binding="mexHttpsBinding"
bindingConfiguration="secureMexBinding"
contract="IMetadataExchange" />
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
I think you need to specify the bindingconfiguration in your <protocolMapping> node since you have a named binding being referenced in your endpoint.
From:
<add binding="basicHttpsBinding" scheme="https" />
to:
<add binding="basicHttpsBinding" scheme="https" bindingConfiguration="basicHttpBinding_eLink" />

Getting 400 Bad Request when trying to use wcf service from another wcf service

I'm trying to call a WCF service from another WCF service, but when I try to call a specific method I get "System.ServiceModel.ProtocolException: 'The remote server returned an unexpected response: (400) Bad Request.'" . Both services are hosted on IIS. This is the configuration of the service I'm calling:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1" maxRequestLength="2000000"/>
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="serviceBehaviour" name="AuthenticationService.WcfService">
<endpoint address="rest" name="AuthEndpoint"
behaviorConfiguration="webBehaviour" binding="webHttpBinding" bindingConfiguration="webBindingConfig"
contract="Interfaces.Wcf.IWcfAuthenticationService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/AuthenticationService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webBehaviour">
<enableWebScript/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="serviceBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webBindingConfig" maxBufferPoolSize="2000000" maxReceivedMessageSize="2000000" >
<readerQuotas maxDepth="2000000" maxStringContentLength="2000000" maxArrayLength="2000000"
maxBytesPerRead="2000000" maxNameTableCharCount="2000000" />
</binding>
</webHttpBinding>
</bindings>
<protocolMapping>
<add binding="webHttpBinding" scheme="http" />
</protocolMapping>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
In the cilent configuration I have:
<client>
<endpoint address="http://localhost/AuthenticationService/WcfService.svc/rest" name="AuthEndpoint"
behaviorConfiguration="webBehaviour"
binding="webHttpBinding"
bindingConfiguration="webBindingConfig"
contract="Interfaces.Wcf.IWcfAuthenticationService" />
</client>
I'm creating the service instance with the ChannelFactory class like this:
var channelFactory = new ChannelFactory<IWcfAuthenticationService>("AuthEndpoint");
var service = channelFactory.CreateChannel();

WCF error 413 Request Entity too la

I have recently a new exception. When I try to call a method with a byte array in parameter I get a 413 error.
I try to change maxBufferSize, maxReceivedMessageSize and maxBufferPoolSize but nothing had changed.
In my app.config of my application I have :
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="soap"
maxReceivedMessageSize="1116553600"
maxBufferPoolSize="1116553600"
maxBufferSize="1116553600"/>
</basicHttpBinding>
<wsHttpBinding>
<binding name="mex" maxReceivedMessageSize="1116553600"
maxBufferPoolSize="1116553600">
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:9804/ServiceBX.svc/soap"
binding="basicHttpBinding" bindingConfiguration="soap" contract="ServiceReferenceBX.ServiceBX"
name="soap" />
</client>
</system.serviceModel>
And in my web.config of my WCF service I have :
<system.serviceModel>
<services>
<service name="BXSportWCFLib.ServiceBX" behaviorConfiguration="MyServiceBehavior">
<endpoint name="rest" address="" binding="webHttpBinding" contract="BXSportWCFLib.ServiceBX" behaviorConfiguration="restBehavior" />
<endpoint name="mex" address="mex" binding="mexHttpBinding" contract="BXSportWCFLib.ServiceBX" />
<endpoint name="soap" address="soap" binding="basicHttpBinding" contract="BXSportWCFLib.ServiceBX" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior" >
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="restBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
I see lot of things on this error but anything I try don't work.
First I like to know in wich file I must modify ?
I try to add bindings and modify my endoint but now when I execute my application I had a : "The requested service can't be activated"
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
</httpModules>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="soap"
maxReceivedMessageSize="116553600"
maxBufferPoolSize="116553600"
maxBufferSize="116553600">
<readerQuotas maxStringContentLength="116533600" />
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="web"
maxReceivedMessageSize="116553600"
maxBufferPoolSize="11653600"
maxBufferSize="116553600">
<readerQuotas maxStringContentLength="116533600" />
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="BXSportWCFLib.ServiceBX" behaviorConfiguration="MyServiceBehavior">
<endpoint name="rest"
address=""
binding="webHttpBinding"
bindingConfiguration="web"
contract="BXSportWCFLib.ServiceBX"
behaviorConfiguration="restBehavior" />
<endpoint name="soap"
address="soap"
binding="basicHttpBinding"
bindingConfiguration="soap"
contract="BXSportWCFLib.ServiceBX" />
<endpoint name="mex"
address="mex"
binding="mexHttpBinding"
contract="IMetaDataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior" >
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="restBehavior" >
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
Thanks
It sounds like you're receiving the error when calling the service, so you need to fix the config file for the service, not the client.
The posted config for the service does not specify any binding configurations, so WCF will use the default settings for the specified values. You need to a) define the binding configurations you want to use and b) assign them to the endpoints. Failure to do both will result in WCF still using the default values.
In your service config, add the following in the <system.serviceModel> section:
<bindings>
<basicHttpBinding>
<binding name="soap"
maxReceivedMessageSize="116553600"
maxBufferPoolSize="116553600"
maxBufferSize="116553600">
<readerQuotas maxStringContentLength="116533600" />
</binding>
</basicHttpBinding>
<webHttpBinding
<binding name="web"
maxReceivedMessageSize="116553600"
maxBufferPoolSize="11653600"
maxBufferSize="116553600">
<readerQuotas maxStringContentLength="116533600" />
</binding>
</webHttpBinding>
</bindings>
Note that you need to specify the configuration for both basicHttpBinding and webHttpBinding.
Next, assign them to the correct endpoints via the bindingConfiguration attribute on the <endpoint> element:
<endpoint name="rest"
address=""
binding="webHttpBinding"
bindingConfiguration="web"
contract="BXSportWCFLib.ServiceBX"
behaviorConfiguration="restBehavior" />
<endpoint name="soap"
address="soap"
binding="basicHttpBinding"
bindingConfiguration="soap"
contract="BXSportWCFLib.ServiceBX" />
Thirdly, your mex endpoint is specifying the wrong contract - it should be IMetaDataExchange:
<endpoint name="mex"
address="mex"
binding="mexHttpBinding"
contract="IMetaDataExchange" />
If you still get the 413 error, you will also want to adjust the maxRequestLength in <httpRuntime> element. This goes in the config file in the <system.webServer> section:
<system.web>
<httpRuntime maxRequestLength="116533600" />
</system.web>
the default for maxRequestLength is 4 MB, but most likely the issue is with the values being used for the bindings on your service.
The solution work !
I had add bindings but I change the IMetaDataExchange and write BXSportWCFLib.ServiceBX and I have not the message "The requested service can't be activated"
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" />
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
</httpModules>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="soap"
maxReceivedMessageSize="116553600"
maxBufferPoolSize="116553600"
maxBufferSize="116553600">
<readerQuotas maxStringContentLength="116533600" />
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="web"
maxReceivedMessageSize="116553600"
maxBufferPoolSize="11653600"
maxBufferSize="116553600">
<readerQuotas maxStringContentLength="116533600" />
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="BXSportWCFLib.ServiceBX" behaviorConfiguration="MyServiceBehavior">
<endpoint name="rest"
address=""
binding="webHttpBinding"
bindingConfiguration="web"
contract="BXSportWCFLib.ServiceBX"
behaviorConfiguration="restBehavior" />
<endpoint name="soap"
address="soap"
binding="basicHttpBinding"
bindingConfiguration="soap"
contract="BXSportWCFLib.ServiceBX" />
<endpoint name="mex"
address="mex"
binding="mexHttpBinding"
contract="IMetaDataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior" >
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="restBehavior" >
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>

WCF REST Service with Windows Authentication and SSL

I have WCF Rest Service that is being consumed by android, iOS and asp.net web application. all endpoint methods return json format so I use webHttpBinding. Problems started when I secured the service by activating Windows authentication(disabled Anonymous before that). When I try to add Service reference from the asp.net web application I receive the following error:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'.
The remote server returned an error: (401) Unauthorized.
When I call endpoints in browser windows dialog is being showed with username and pass and everything works fine, but When I try to add the reference I receive the error. I'm also using SSL and the service has only https address.
web.config wcf rest service:
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" executionTimeout="90" maxRequestLength="20000" useFullyQualifiedRedirectUrl="false" requestLengthDiskThreshold="8192" />
<authentication mode="Windows" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<bindings>
<webHttpBinding>
<binding name="WebHttpEndpointBinding" maxReceivedMessageSize="200000000" maxBufferPoolSize="200000000">
<readerQuotas maxDepth="32" maxArrayLength="2000000000" maxStringContentLength="2000000000" />
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="restSrvService.restSrvRestService" behaviorConfiguration="serviceBehavior">
<endpoint address="" name="webHttpEndpoint" binding="webHttpBinding" bindingConfiguration="WebHttpEndpointBinding" behaviorConfiguration="web" contract="restSrvService.IrestSrvRestService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceAuthenticationManager authenticationSchemes="IntegratedWindowsAuthentication" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<endpointDiscovery enabled="true">
</endpointDiscovery>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
web.config web application:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"></modules>
</system.webServer>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="WebHttpEndpointBinding" bypassProxyOnLocal="true" useDefaultWebProxy="true" maxReceivedMessageSize="200000000" maxBufferPoolSize="200000000">
<readerQuotas maxDepth="32" maxArrayLength="2000000000" maxStringContentLength="2000000000" />
<security mode="Transport">
<transport clientCredentialType="Windows"></transport>
</security>
</binding>
</webHttpBinding>
</bindings>
<client>
<endpoint address="https://serviceAddress/restSrvRestService.svc/"
binding="webHttpBinding" bindingConfiguration="WebHttpEndpointBinding"
contract="restSrvService.IrestSrvRestService" behaviorConfiguration="webEndpoint" name="WebHttpEndpoint">
<identity>
</identity>
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="webEndpoint">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>

Disabling X.509 certificate validation in .NET with WCF service

I am trying to set up message security in a WCF service and disable the X.509 certificate validation in the process. I'd like to validate the client with a username and password only and not validate the server at all. At least for now.
Referring to the first answer here:
How do I tell WCF to skip verification of the certificate?
How do I achieve the following programmatically on the client?
<behavior name="DisableServiceCertificateValidation">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="Custom"
customCertificateValidatorType="MyCertificateValidator, Client"
revocationMode="NoCheck" />
</serviceCertificate>
</clientCredentials>
</behavior>
I have got this:
With myServiceClient.ClientCredentials
.UserName.UserName = "username"
.UserName.Password = "password"
.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom
.ServiceCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck
End With
I can't work out how to set the "customCertificateValidatorType" and how to wire it to the MyCertificateValidator class.
Does this bypass the requirement of a client certificate, a server certificate or both?
Here is my server web.config file.
<?xml version="1.0"?>
<configuration>
<system.web>
<customErrors mode="Off"/>
<trust level="Full"/>
<compilation debug="true"/>
</system.web>
<system.serviceModel>
<services>
<service name="HelloWorldService.HelloWorldService" behaviorConfiguration="BehaviourMessageSecurity">
<endpoint address ="" binding="wsHttpBinding" contract="HelloWorld.IHelloWorldService" bindingConfiguration="BindingMessageSecurity"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://www.example.com/HelloWorldService.svc"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="BehaviourMessageSecurity">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="HelloWorldService.ServiceAuthenticator, HelloWorldService" />
<serviceCertificate findValue="localhost" x509FindType="FindBySubjectName"
storeLocation="LocalMachine" storeName="My" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="BindingMessageSecurity">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Czustom means you write your own validation method. If you don't want to check the certificate at all, use None:
.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None

Categories