Selfhosting WCF Service and basicHttpBinding: A Windows identity that represents the caller is not provided by binding - wcf

I have a self hosting wcf service in a console application.
A simple self hosting service is no problem, there are enough examples.
Now I want to impersonate the caller of the wcf service. Although I followed this msdn article http://msdn.microsoft.com/en-us/library/ff648505.aspx I get follwing error:
The contract operation 'GetProduct' requires Windows identity for automatic impersonation. A Windows identity that represents the caller is not provided by binding
Here is my App.config of the wcf service in the CONSOLE application:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="SelfHostingWCFService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<SelfHostingWCFService.Properties.Settings>
<setting name="URL" serializeAs="String">
<value>http://localhost:8081/ProductService</value>
</setting>
</SelfHostingWCFService.Properties.Settings>
</applicationSettings>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ProductServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization impersonateCallerForAllOperations="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="SelfHostingWCFService.ProductService"
behaviorConfiguration="ProductServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8081/ProductService"/>
</baseAddresses>
</host>
<endpoint address="soap" binding="basicHttpBinding" contract="SelfHostingWCFService.IProductService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
</configuration>
Here ist the Service Code:
public class ProductService : IProductService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public Product GetProduct(int productId)
{
Product prod = new Product();
prod.ID = productId;
prod.Name = productId.ToString() + " XDS";
return prod;
}
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string User()
{
string Name = string.Empty;
if (OperationContext.Current.ServiceSecurityContext != null)
Name = OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name;
if (ServiceSecurityContext.Current != null)
Name = ";" + ServiceSecurityContext.Current.WindowsIdentity.Name;
Name = ";" + Thread.CurrentPrincipal.Identity.Name;
return Name;
}
}
Here is the client code:
private void button1_Click(object sender, EventArgs e)
{
ProductService.ProductService srv = new ProductService.ProductService();
//srv.Credentials = System.Net.CredentialCache.DefaultCredentials;
ProductService.Product prod = srv.GetProduct(1, true);
label1.Text = prod.Name;
label2.Text = srv.User();
}
What do I making wrong?
Please let me know.
Can I use basicHTTPBinding or must I use wsHTTPBinding?
many thanks for your help

I don't see your client-side configuration - you may need to set your client binding Security.Transport.ClientCredentialType
See here: http://msdn.microsoft.com/en-us/library/ms729700(v=vs.110).aspx

Related

WCF service host cannot find any service metadata. Please Check if metadata is enabled

My App.config file is
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="WcfJsonRestService.Service1">
<endpoint address="http://localhost:8733/service1"
binding="webHttpBinding"
contract="WcfJsonRestService.IService1"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
My service1.cs code is as below
using System;
using System.ServiceModel.Web;
namespace WcfJsonRestService
{
public class Service1 : IService1
{
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "data/{id}")]
public Person GetData(string id)
{
// lookup person with the requested id
return new Person()
{
Id = Convert.ToInt32(id),
Name = "Leo Messi"
};
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
}
Initially this was giving issue as
WCF Service Host Configuration - Please try changing the HTTP port to 8733
So I had followed Executing the following code in CMD
netsh http add urlacl url=http://+:8733/ user=WORK\Clara
After executing this code I am facing new error as below
How can I resolve this issue?
I have also tried updating the App.Config as said over below link but then after I was getting some another error
WCF service host cannot find any service metadata
You are missing service metadata behavior configuration. Please add below configuration:
<configuration>
<system.serviceModel>
<services>
<service name="WcfJsonRestService.Service1">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733"/>
</baseAddresses>
</host>
<endpoint address="service1"
binding="webHttpBinding"
contract="WcfJsonRestService.IService1"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled ="true"/>
</behavior>
</serviceBehaviors>
</behaviors>

Windows Service Bus 1.0, Appfabric, Netmessagingbinding failuring

I seem to run into the same problem over and over again when I am trying to host a WCF service in Windows Server AppFabric that uses netmessagingbinding to receive messages from Windows Service Bus 1.0 queues. AppFabric aborts the service, so if I press F5 on service?wsdl then I sometimes get failures, sometimes I get a nice WSDL generated. Where is my mistake? It is rather impossible to find an example that uses AppFabric, netmessagingbinding and Windows Service Bus (not Azure), so I haven't been able to finde my mistake...
[ServiceContract]
public interface ISBMessageService
{
[OperationContract(IsOneWay = true, Action = "DoSomething")]
[ReceiveContextEnabled(ManualControl = true)]
void DoSomething(string something);
}
[ServiceBehavior]
public class SBMessageService : ISBMessageService
{
[OperationBehavior]
public void DoSomething(string something)
{
Trace.WriteLine(String.Format("You sent {0}", something));
// Get the BrokeredMessageProperty from the current OperationContext
var incomingProperties = OperationContext.Current.IncomingMessageProperties;
var property = incomingProperties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;
ReceiveContext receiveContext;
if (ReceiveContext.TryGet(incomingProperties, out receiveContext))
{
receiveContext.Complete(TimeSpan.FromSeconds(10.0d));
}
else
{
throw new InvalidOperationException("...");
}
}
}
<?xml version="1.0"?>
<configuration>
<appSettings>
<!-- Service Bus specific app setings for messaging connections -->
<add key="Microsoft.ServiceBus.ConnectionString"
value="Endpoint=sb://LRNcomp/LRNnamespace"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<httpRuntime/>
</system.web>
<system.serviceModel>
<!-- These <extensions> will not be needed once our sdk is installed-->
<extensions>
<bindingElementExtensions>
<add name="netMessagingTransport" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingElementExtensions>
<bindingExtensions>
<add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
<behaviorExtensions>
<add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" 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="True" httpHelpPageEnabled="True"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="securityBehavior">
<transportClientEndpointBehavior>
<tokenProvider>
<sharedSecret issuerName="owner" issuerSecret="somthing"/>
</tokenProvider>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<netMessagingBinding>
<binding name="messagingBinding" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:03:00" sendTimeout="00:03:00" sessionIdleTimeout="00:01:00" prefetchCount="-1">
<transportSettings batchFlushInterval="00:00:01"/>
</binding>
</netMessagingBinding>
</bindings>
<services>
<service name="SBExamples.SBMessageService">
<endpoint name="Service1" address="sb://LRNcomp:9354/LRNnamespace/test/myqueue2" binding="netMessagingBinding" bindingConfiguration="messagingBinding" contract="SBExamples.ISBMessageService" behaviorConfiguration="securityBehavior"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
An error in the WCF contract generated many strange exceptions, like my transport channel was aborted. Proper sharing of contract between sender and receiver did the trick.

wsHttpBinding not working in a WCF service selfhosted; SOAP-based bindings do work

I have a simple WCF Service shown below.
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest)]
string GetData(int value);
}
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
The server Web.config file is
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpEndpointBehavior">
<webHttp faultExceptionEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="serviceBehaviourDebug">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" 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="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Diws.Service1" behaviorConfiguration="serviceBehaviourDebug">
<endpoint
address="/basicHttp"
binding="basicHttpBinding"
contract="Diws.IService1"/>
<endpoint
address="/webHttp"
binding="webHttpBinding"
behaviorConfiguration="webHttpEndpointBehavior"
contract="Diws.IService1"/>
<endpoint
address="/wsHttp"
binding="wsHttpBinding"
contract="Diws.IService1"/>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
The client is a console app whose App.config is this.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpEndpointBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
<wsHttpBinding>
<binding name="WsHttpBinding_IService1" />
</wsHttpBinding>
<webHttpBinding>
<binding name="WebHttpBinding_IService1" />
</webHttpBinding>
</bindings>
<client>
<endpoint
address="http://localhost:50001/Service1.svc/basicHttp"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1"
contract="ServiceReference1.IService1"
name="BasicHttpEndpoint_IService1" />
<endpoint
address="http://localhost:50001/Service1.svc/webHttp"
behaviorConfiguration="webHttpEndpointBehavior"
binding="webHttpBinding"
bindingConfiguration="WebHttpBinding_IService1"
contract="ServiceReference1.IService1"
name="WebHttpEndpoint_IService1" />
<endpoint
address="http://localhost:50001/Service1.svc/wsHttp"
binding="wsHttpBinding"
bindingConfiguration="WsHttpBinding_IService1"
contract="ServiceReference1.IService1"
name="WsHttpEndpoint_IService1"/>
</client>
</system.serviceModel>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
</configuration>
And the client program is this.
class Program
{
static void Main(String[] args)
{
String response = "";
Service1Client basicHttpClient = new Service1Client("BasicHttpEndpoint_IService1");
response = basicHttpClient.GetData(10);
basicHttpClient.Close();
Console.WriteLine(response);
///* Some communication exception
Service1Client webHttpClient = new Service1Client("WebHttpEndpoint_IService1");
response = webHttpClient.GetData(20);
webHttpClient.Close();
Console.WriteLine(response);
//*/
Service1Client wsHttpClient = new Service1Client("WsHttpEndpoint_IService1");
response = wsHttpClient.GetData(30);
wsHttpClient.Close();
Console.WriteLine(response);
Console.WriteLine();
Console.WriteLine("Done");
Console.ReadLine();
}
}
The basicHttpClient and the wsHttpClient work perfectly. However, the webHttpClient throws the exception "System.ServiceModel.CommunicationException was unhandled, HResult=-2146233087, Message=Internal Server Error"
I cannot debug on the servers side as Visual Studio 2012 says
"Unable to automatically debug 'MyProject'. The remote procedure could not be debugged. This usually indicates that debugging has not been enabled on the server."
However, debugging is enabled. I wasn't able to get any insights from using the SvcTraceViewer with diagnostics turned on.
My main interest is figuring out why the REST call using WebHttpBinding is failing, but help getting server side debugging working would be appreciated as well. I'm debugging both the client and the server in VS2012 using multiple startup projects. Localhost is the only server involved.
I understand that the REST endpoint won't show up in WcfTestClient since it provides no metadata exchange, but I expected to be able to call the service through that endpoint and I see no difference between my code and examples of calling RESTful WCF services.
For accessing a REST endpoint try making a HTTP POST request using a browser or HttpClient to the URL : $http://localhost:50001/Service1.svc/webHttp/GetData$. When you use webHttpClient as you do in your code to make a call to the service you are sending a SOAP request which a REST endpoint cannot process. I believe that's the reason your other two endpoints work fine but not this one.

WCF rest service: unable to call methods

Please tell me I'm doing something stupid in setting up my wcf rest service.
I've create a web application and added a wcf service to it.
Here is my web.config
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WebApplication1.Service1">
<endpoint address="../Service1" behaviorConfiguration="httpBehavior"
binding="webHttpBinding"
contract="WebApplication1.IService1"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="httpBehavior">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
And my service interface:
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(UriTemplate = "data/{value}", ResponseFormat = WebMessageFormat.Json)]
Person GetData(string value);
}
And my service code:
public class Service1 : IService1
{
public Person GetData(string value)
{
return new Person()
{
Id = Convert.ToInt32(value),
Name = "John Doe"
};
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
I have no problems browsing to the service
http://localhost/RoleProviderSite/Service1.svc
but as soon as I add the data/10
http://localhost/RoleProviderSite/Service1.svc/data/10
"There was no channel actively listening at 'http://mymachinename/RoleProviderSite/Service1.svc/data/10"
I would have thought that adding the "[WebGet(UriTemplate = "data/{value}", ResponseFormat = WebMessageFormat.Json)]" would mean that this url would be accessible, but maybe I'm missing something?
I'm using :
Internet Information Services, Version: 5.1
and XP OS
Thanks very much for any help.
remove the address in the endpoint and your URI should work as expected. You cannot use relative addressing like that for your endpoint

simultaneous calls handling in WCF

I'm new to .net and knows very little about WCF, so bear with me if any silly questions asked. I'm wondering how WCF handles simultaneous calls in SELF-HOST scenario if my code doesn't explicitly spawn any thread. So after read a lot on the stackoverflow, I created a test app but it seems not working. Please advise. Thanks a lot.
Please note ...
My question is only about WCF SELF HOSTING, so please don't refer to any IIS related.
I'm using webHttpBinding.
I understand there are maxConnection and service throttling settings, but I'm only interested in 2 simultaneous calls in my research setup. So there should be no max conn or thread pool concern.
My test service is NOT using session.
Code as below ...
namespace myApp
{
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
public interface ITestService
{
[OperationContract]
[WebGet(UriTemplate="test?id={id}")]
string Test(int id);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
ConcurrencyMode = ConcurrencyMode.Multiple)]
public class TestService : ITestService
{
private static ManualResetEvent done = new ManualResetEvent(false);
public string Test(int id)
{
if (id == 1)
{
done.Reset();
done.WaitOne();
}
else
{
done.Set();
}
}
}
}
app.config ...
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name = "TestEndpointBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name = "myApp.TestService">
<endpoint address = "" behaviorConfiguration="TestEndpointBehavior"
binding = "webHttpBinding"
contract = "myApp.ITestService">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/test/"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
<system.web>
<sessionState mode = "Off" />
</system.web>
How I tested ...
Once had the application running, I opened my browser, FF in case, made one call to http://localhost:8080/test/test?id=1 . This request put the app to suspend waiting for signal, i.e. WaitOne. Then made another call in another browser tab to http://localhost:8080/test/test?id=2. What's expected is that this request will set the signal and thus the server will return for both requests.
But I saw the app hang and the Test function never got entered for the 2nd request. So apparently my code doesn't support simultaneous/concurrent calls. Anything wrong?
You can use single class to setup your wcf service and discard interface. You need to add global.asax file also. After you make the second call, all of them will return "finished".
This configuration does what you want.
Create TestService.cs with :
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
ConcurrencyMode = ConcurrencyMode.Multiple)]
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
public class TestService
{
private static ManualResetEvent done = new ManualResetEvent(false);
[OperationContract]
[WebGet(UriTemplate = "test?id={id}")]
public string Test(int id)
{
if (id == 1)
{
done.Reset();
done.WaitOne();
}
else
{
done.Set();
}
return "finished";
}
}
web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<system.serviceModel>
<standardEndpoints>
<webHttpEndpoint>
<!--
Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
via the attributes on the <standardEndpoint> element below
-->
<standardEndpoint name="" helpEnabled="false" > </standardEndpoint>
</webHttpEndpoint>
</standardEndpoints>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 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>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
Global.asax file:
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("testservice", new WebServiceHostFactory(), typeof(TestService)));
}
}