Exposing WCF Services Via HTTP when not hosted in IIS - wcf

Like the title says, we need to set up WCF services between a .NET app, and a Adobe AIR app. We don't want to run IIS on the machine, and would much prefer to install and run the WCF services hosted within a windows service.
However, I am uncertain of doing that will let us use HTTP as the transport, of does that only work within IIS? I was able to set things up to use the TCP transport, but that doesn't interop with AIR nearly as nice as using HTTP.
EDIT: Some test code I've been using to see if this works:
Regular console app:
static void Main()
{
using (ServiceHost host = new ServiceHost(typeof(TestService)))
{
host.Open();
}
Console.WriteLine("Waiting...");
Console.ReadLine();
}
TestService is a simple HelloWorld type service.
In the App.Config:
<configuration>
<system.serviceModel>
<services>
<service name="WCFExample2.TestService" behaviorConfiguration="WCFExample2.TestServiceBehavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/Design_Time_Addresses/WCFExample2/Service1/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="wsHttpBinding" contract="WCFExample2.ITestService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFExample2.TestServiceBehavior">
<!-- 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>
</system.serviceModel>
</configuration>

You should have no trouble setting up a Windows NT Service which hosts your WCF service and exposes HTTP endpoints - no need for IIS (but the WCF runtime will use the http.sys kernel mode driver).
Have you tried and failed? If so - can you show us what you had, and how and where it failed?
As a bare minimum, you'd probably want to have something like this config on your service side:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="Default"
sendTimeout="00:05:00"
maxBufferSize="500000"
maxReceivedMessageSize="500000" >
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="Namespace.MyWCFService"
behaviorConfiguration="Default">
<host>
<baseAddresses>
<add baseAddress="http://MyServer:8282/MyWCFService/"/>
</baseAddresses>
</host>
<endpoint
address="basic"
binding="basicHttpBinding" bindingConfiguration="Default"
contract="Namespace.IMyWCFService" />
</service>
</services>
</system.serviceModel>
Of course, you might need to tweak things like the timeout settings, buffer size settings etc. on your binding, the security mode, and quite possibly other settings as you need them to be.
Marc

You could skip all the config and use the WebServiceHost class (which will do it all for you in a fairly standard way). Get that working then look into tailoring the config manually to meet any extra requirements you may have.
All the info you need is here WebServiceHost on MSDN it's a very straightforward way to get started on a custom (i.e. non IIS) hosted http service.
Mike

Apart from the config file settings one more thing to consider.
If you selfhost in a windows service, a http endpoint then
Make the service login account a local admin on the machine
or
You have to register the service account for the http namespace with http.sys.
This step has to be done by a local admin but only once in each machine. You can use the HttpSysCfg tool to do this in XP/win 2003. For vista/win 2008 use netsh.

Related

Hosting a WCF service with Net.TCP

I am totally new to this and trying to host the simplest WCF service with a net.tcp binding
I have Windows 7 Professional and IIS7 and have enabled NON http activation.
I start a new WCF Service application
project in vs2010 and compile it.
NOHTING ELSE!
I delete all my IIS
Websites and add a new called WCFHost
I open up WcfTestClient.exe and adds
http://localhost/Service1.svc the application finds it
The Web.config looks like this (untouched)
<system.serviceModel>
<services>
<service name="WcfService2.Service1" behaviorConfiguration="WcfService2.Service1Behavior">
<endpoint address="" binding="wsHttpBinding" contract="WcfService2.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService2.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>
</system.serviceModel>
So far, so good. But what about that net.tcp binding. I add the "enabledProtocols" attribute so my applicationHost.config looks like this
<site name="WCFHOST" id="3">
<application path="/" applicationPool="WCFHOST" enabledProtocols="http,net.tcp,net.pipe,net.msmq">
<virtualDirectory path="/" physicalPath="C:\Prosjekter\temp\TestService\TestService" />
</application>
<bindings>
<binding protocol="net.tcp" bindingInformation="808:*" />
<binding protocol="http" bindingInformation="*:80:" />
</bindings>
</site>
Then I go to the IIS WCFHost website and add binding net.tcp 808:*
And then I modify my web.config for the WCF Service to look like this. (just changed the binding on the endpoints)
<system.serviceModel>
<services>
<service name="WcfService2.Service1" behaviorConfiguration="WcfService2.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="netTcpBinding" contract="WcfService2.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfService2.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>
</system.serviceModel>
When I now try to add the service net.tcp://localhost:808/Service1.svc in my WcfTestClient.exe I get the error
Error: Cannot obtain Metadata from net.tcp://localhost/Service1.svc
TCP-errorcode 10061: No connection could be made because the target machine actively refused it.... 127.0.0.1:808
My firewall is turned off.
I have seen one thing, though.. when using netstat -a the 808 port is not listed there.. should it?
Can someone help me just creating my first WCF service with nettcp binding?
As Tocco says, check that the service is running. You can do this by checking:
netstat /an | find /i "808 "
And it should show:
TCP 0.0.0.0:808 0.0.0.0:0 LISTENING
TCP [::]:808 [::]:0 LISTENING
if the service is running correctly.
To get it to start if it's not already working, you can issue:
sc start NetTcpActivator
from the command line to ttry to start it.
Even before that, make sure that the non-HTTP activation windows components are installed.
Also check that the services are actually running. I had a problem where they would not necessarily start after a reboot.
The net.tcp bindings are enabled on IIS for requests on 808?
Check it on IIS manager / bindings.
See it
I had the same error message and resolved it by not only creating a TCP binding on the site as follows:
But also enabling the net.tcp protocol in Advanced Settings:

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.

WCF Service netTCPbinding

I want to use netTCPbinding, so I've changed my web config as below. I'm experiencing this error:
Could not find a base address that matches scheme net.tcp for the endpoint with binding NetTcpBinding. Registered base address schemes are [http].
How can this be solved?
<services>
<service name="DXDirectory.DXDirectoryService" behaviorConfiguration="DXDirectory.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="netTcpBinding" bindingConfiguration="WindowsSecured" contract="DXDirectory.IDXDirectoryService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:2582/DXDirectoryService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DXDirectory.Service1Behavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="false" />
<!-- 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" />
<serviceAuthorization principalPermissionMode="UseWindowsGroups" />
<!--<serviceCredentials>-->
<!--<userNameAuthentication userNamePasswordValidationMode="Custom"
membershipProviderName="CustomUserNameValidator"/>-->
<!--</serviceCredentials>-->
</behavior>
</serviceBehaviors>
</behaviors>
HMm... you've added the base address to your services/host section ok.
Quick question: are you self-hosting, or hosting in IIS ?? Which version of IIS ??
IIS5/6 only support HTTP connections - you cannot host a NetTCP in IIS 5/6.
In IIS7, you have to manually go through a series of steps to enable non-HTTP bindings, but it's possible. See this MSDN article on how to achieve this.
Self-hosting is the best option - you get all bindings and are in total control of your service being hosted.
Marc
Here is a NetTcpBinding basic example from msdn. See if this can help you.
EDIT:
And here is a related SO question.
I cant see section in your config file, can u please
please add this
<netTcpBinding>
<binding name="WindowsSecured">
<security mode="none"/>
</binding>
</netTcpBinding>

Setting Transport level security on webHttp WCF service

I am trying to set transport level security on a webHttp binding WCF service my current config looks like this
<system.serviceModel>
<client>
<endpoint binding="webHttpBinding" bindingConfiguration="webHttp"
contract="PrimeStreamInfoServices.IService1" name="Client" />
</client>
<bindings>
<webHttpBinding>
<binding name="webHttp" maxBufferPoolSize="1500000" maxReceivedMessageSize="1500000" maxBufferSize="1500000">
<security mode="Transport">
<transport clientCredentialType="None"
proxyCredentialType="None"
realm="string" />
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="PrimeStreamInfoServices.Service1" behaviorConfiguration="PrimeStreamInfoServices.Service1Behavior">
<!-- Service Endpoints -->
<endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttp" contract="PrimeStreamInfoServices.IService1">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="PrimeStreamInfoServices.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>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true" />
</diagnostics>
however when i run my service i get an exception:
Could not find a base address that matches scheme https for the endpoint with binding WebHttpBinding. Registered base address schemes are [http].
I know im missing something, and I have been trying various things I cant figure it out, anyone got some input on what i have to do?
Yes - switch to HTTPS, with a suitable certificate. Transport security, in the case of HTTP is provided by an SSL channel. You can't have WS* transport security over plain HTTPS
Ignore my previous answer, I was thinking wsHttpBinding not webHttpBinding.
It is the address that you use to call the service that must start with https.
https://machineName/ServiceName
Can you try to add a base address (inside the <host> element of your service config) which is https ? Are you adding a (or multiple) base address(es) in code?
<service name="PrimeStreamInfoServices.Service1"
behaviorConfiguration="PrimeStreamInfoServices.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress="https://localhost:8080/YourService.svc" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<endpoint ......
</service>
Not 100% sure if that works with the webHttpBinding, but give it a try!
Marc
Remember that besides the right WCF config, you also need to configure IIS property to enable SSL on it (including setting the right X.509 certificate for SSL). The docs have some decent information on how to do it.

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)
{...}