Activation error in WCF web-service using basicHttpBinding, Windpws-Authentication & impersonation - wcf

I am trying to host a WCF web service in IIS using Windows Authentication. Due to restrictions, we have to use the basicHttpBinding & use impersonation (impersonate the caller's identity for accessing resources down the chain).
I have declaratively enabled impersonation on the operation contract of my WCF service:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
My web.config is:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basic">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows">
</transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service name="NotesService">
<endpoint address="http://Client1.osp.local:15000/NotesService/NotesService.svc" bindingConfiguration="basic" binding="basicHttpBinding" contract="NotesService.ServiceContract.INotesService">
<identity>
<servicePrincipalName value="HTTP/Client1.osp.local:15000"/>
</identity>
</endpoint>
</service>
</services>
</system.serviceModel>
However, I am getting an activation error. What am I missing?
The error I am getting is:
The contract operation 'Process' requires Windows identity for automatic
impersonation. A Windows identity that represents the caller is not provided by
binding ('BasicHttpBinding','http://tempuri.org/') for contract
('NotesService','http://tempuri.org/'.

Assuming you are using WCF 4.0, then I think you are seeing an artefact of a WCF 4 feature called default endpoints.
In the service name you need to provide the fully qualified name of the service (including the namespace). Assuming NotesService is in a namespace then when you create the ServiceHost it doesn;t find a match in the config file. If you supply an HTTP base address in the ServiceHost constructor then it will wire up the basicHttpBinding with its default configuration (no authentication) which would produce the error you are seeing

Related

WCF/SSL error: Failed to lookup a channel to receive an incoming message

I've been having a difficult time getting a WCF call in Silverlight to work when using SSL. I've gotten it to a point where WCF tracing says the endpoint is listening but when my code tries to call a function on it WCF Tracing shows the error:
Failed to lookup a channel to receive an incoming message. Either the endpoint or the SOAP action was not found.
If I browse to the services URL I properly get the service page, but calling it in code it always fails. Again, this only happens on HTTPS, not before when I was using HTTP. Of course there were a number of config changes to add to use SSL. I should note that the WCF Domain Services functions work fine over SSL, just not the WCF Service. Below are my various config file sections
Web.config
<system.serviceModel>
<domainServices>
<endpoints>
<add name="OData" type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</endpoints>
</domainServices>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<behaviors>
<endpointBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding" maxReceivedMessageSize="20000" maxBufferSize="20000">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
<readerQuotas maxArrayLength="20000" maxStringContentLength="20000" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="PictureService">
<endpoint address="https://MyServer/AdvisorDev/PictureService.svc"
binding="basicHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="PictureService.IPictureService"/>
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
ServiceReferences.ClientConfig:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IPictureService" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://MyServer/AdvisorDev/PictureService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPictureService"
contract="PictureService.IPictureService" name="BasicHttpBinding_IPictureService" />
</client>
</system.serviceModel>
</configuration>
Create client:
PictureService.PictureServiceClient client = new PictureService.PictureServiceClient();
I am running this on my Dev machine using VS 2012 and using IIS as my web server. IIS is using a self-signed certificate. When my site first loads I do get the "There is a problem with this website's security certificate" error, click continue, and the rest of the application runs fine again including the Domain Service calls which use a dynamically created proxy. I create my proxy for this failing WCF service using "Add Service Reference"
One of my sources for SSL is this:
http://msdn.microsoft.com/en-us/library/hh556232(v=vs.110).aspx
This is the service I implemented:
http://www.silverlightshow.net/items/Uploading-and-downloading-images-from-WCF-in-Silverlight.aspx
I appreciate all advice on this, thank you.
It turns out this error was caused by an incorrect namespace in the Service name and contract attributes in the web.config for this service.
Just in case anyone else is having this issue as well, I was receiving the same error. The fix turned out to be removing inheritance from three of my classes.
My WCF service was returning a List<MyObject> and three classes inherited from the "MyObject" class. This error was thrown when one of the inheriting classes was included in the list.
Ex:
public class MyObject
public class MyObjectTwo : MyObject
...
List<MyObject> returnList;
MyObjectTwo addingThisBreaksTheService = new MyObjectTwo();
returnList.Add(addingThisBreaksTheService);
return returnList; // Exception thrown after this statement

Equivalent web.config settings for WebServiceHostFactory

I'm having problems finding how to setup my web.config to use the same settings as using the WebServiceHostFactory on my RESTful WCF service. Does anyone know what the equivalent web.config would look like instead of using that factory, or how I can find it (assume I should be able to attach and find the endpoint objects etc?).
I need to change a couple of small things that the factory is using, and set the authentication to none, so it will play nicely with IIS (currently getting IIS specified authentication schemes 'IntegratedWindowsAuthentication, Anonymous' - and I cant change the IIS settings).
You should be able to add a reference to your service in the Web.config under the system.serviceModel section.
By specifying the full name of the service implementation as the name, of the service element you can then configure it to use specific end points and behaviours.
Hope this helps.
I have used a similar config to below for controlling my WCF Rest Services.
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<protocolMapping>
<add scheme="http" binding="httpBehavior"/>
</protocolMapping>
<bindings>
<webHttpBinding>
<binding name="serviceBinding">
<security mode="Transport" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="httpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="{fullname of your service}">
<endpoint address="" behaviorConfiguration="httpCommerceBehavior" binding="webHttpBinding" bindingConfiguration="serviceBinding" contract="{Service Contract full name}>
</endpoint>
</service>
</services>
</system.serviceModel>

Getting an Security setting exception while accessing a WCF service

Following are binding configurations of my WCF service.
Anonymous access: off
Basic authentication: on
Integrated Windows authentication: off !!
support HTTP protocol .
I am getting an following exception while accessing my WCF service:
Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType ="Basic" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="WMWcfWebServiceLib.Service1Behavior"
name="WMWcfWebServiceLib.WMWcfWebService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="MyBinding"
contract="WMWcfWebServiceLib.IWMWebService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/Design_Time_Addresses/WMWcfWebServiceLib/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WMWcfWebServiceLib.Service1Behavior">
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above 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>
Please Help!!
Edit
I am able to access the WCF service through the web browser with the following changes:
Changes the security mode to TransportCredentialOnly and Removed the Mex Endpoint, but now as obvious I am not able to create the proxy on the client side.
Please let me know where I am wrong ?
If you want to support HTTP only your configuration is not used at all because mode="Transport" demands HTTPS. First find why config is not used (probably wrong type name in service element). Next change security mode to TransportCredentialOnly. But be aware that TransportCredentialOnly + Basic authentication means that HTTP requests will contain plain text Windows user name and password. In most cases such implementation will not pass any security audit.
Edit:
You can create proxy without mex endpoint if you still support httpGetEnabled in service metadata behavior.

How can I use WCF with the basichttpbinding only , SSL and Basic Authentication in IIS?

Is it possible to setup a WCF service with SSL and Basic Authentication in IIS using only the BasicHttpBinding-binding?
(I can’t use the wsHttpBinding-binding)
The site is hosted on IIS 7, with the following authentication set up:
Anonymous access: OFF
Basic authentication: ON
Integrated Windows authentication: OFF
Service Config:
<services>
<service name="NameSpace.SomeService">
<host>
<baseAddresses>
<add baseAddress="https://hostname/SomeService/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding"
bindingNamespace="http://hostname/SomeMethodName/1"
contract="NameSpace.ISomeInterfaceService"
name="Default"
/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpsGetEnabled="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"/>
<exceptionShielding/>
</behavior>
</serviceBehaviors>
</behaviors>
I tried 2 types of bindings with two different errors:
1. IIS Error:
'Could not find a base address that matches scheme http for the endpoint with binding BasicHttpBinding. Registered base address schemes are [https].
<bindings>
<basicHttpBinding>
<binding>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
2. IIS Error:
Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service.
<bindings>
<basicHttpBinding>
<binding>
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
Does anyone know how to configure this correctly? (if is it possible?)
After some digging and asking some questions to a few colleagues, we finally solved the problem.
Important to understand is there are 2 aspects of security in this case. The IIS security and the WCF security.
IIS security: Enable SSL & enable Basic Authentication. Disable Anonymous Authentication.
(Of course, create a windows account/group and set the permissions on your application in IIS.)
WCF security: Because the binding is only a BasicHttpBinding, the service doesn't require to valid anything. IIS is responsible for this.
The binding configuration of the service:
<bindings>
<basicHttpBinding>
<binding>
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
And finally, to resolve the first error, we deleted the mex Endpoint. This endpoint requires a HTTP binding.
Deleted:
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>

IIS hosted WCF-service + Windows auth in IIS + TransportCredentialOnly/Windows auth in basicHttpBinding

I want to create a WCF-service hosted in IIS6 and disable anonymous authentication in IIS. And don't use SSL.
So only way I have is to use basicHttpBinging with TransportCredentialOnly, itsn't it?
I create a virtual directory, set Windows Integrated Auth and uncheck "Enable Anonymous Access".
Here's my web.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="Samples.ServiceFacadeService" behaviorConfiguration="ServiceFacadeServiceBehavior">
<endpoint address="" binding="basicHttpBinding" bindingName="MyBinding"
contract="Samples.IServiceFacadeService">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceFacadeServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
You can see that I even haven't included MEX-enpoint for metadata exchange. Just one endpoint and one binding for it with TransportCredentialOnly security.
But when I tries to start service (invoking a method throught client proxy) I got such exception in the EventLog:
Exception:
System.ServiceModel.ServiceActivationException:
The service
'/wcftest/ServiceFacadeService.svc'
cannot be activated due to an
exception during compilation. The
exception message is: Security
settings for this service require
'Anonymous' Authentication but it is
not enabled for the IIS application
that hosts this service.. --->
System.NotSupportedException: Security
settings for this service require
'Anonymous' Authentication but it is
not enabled for the IIS application
that hosts this service.
I have no idea why my service require Anonymous auth? Why?
The answer found jezell. Thanks.
I mixed up bindingName and bindingConfiguration :
<endpoint address="" binding="basicHttpBinding" bindingName="MyBinding"
contract="Samples.IServiceFacadeService">
</endpoint>
That's right:
<endpoint address="" binding="basicHttpBinding" **bindingConfiguration**="MyBinding"
contract="Samples.IServiceFacadeService">
</endpoint>
The MEX endpoint may still be the problem (see this post). Try disabling MEX like this:
<services>
<!-- Note: the service name must match the configuration name for the service implementation. -->
<service name="MyNamespace.MyServiceType" behaviorConfiguration="MyServiceTypeBehaviors" >
<!-- Add the following endpoint. -->
<!-- Note: your service must have an http base address to add this endpoint. -->
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors" >
<!-- This disables it. -->
<serviceMetadata httpGetEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Here is a good post on securing MEX.
Use basicHttpBinding for your mex endpoint and apply the same bindingConfiguration:
To get VS wcf service project (new sample project) to work with authentication under IIS, you have to:
1) Allow Anonymous access in IIS
2) Prefix your public methods with a attribute like this:
[PrincipalPermission(SecurityAction.Demand, Role = "MyADGroup")]
public string SendMyMessage(string Message)
{...}