Contract requires Session, but Binding ‘WSHttpBinding’ doesn’t support it or isn’t configured properly to support it - wcf

I have specified the service contract to require the session.
[ServiceContract(SessionMode = SessionMode.Required)]
public interface ITicketSales
{
}
The service decorated like this:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
public class TicketSalesService : ITicketSales
{
}
Here is my App.config file:
<system.serviceModel>
<services>
<service name="InternetRailwayTicketSales.TicketSalesImplementations.TicketSalesService" behaviorConfiguration="defaultBehavior">
<host>
<baseAddresses>
<add baseAddress = "https://localhost/TicketSales/"></add>
</baseAddresses>
</host>
<endpoint address="MainService" binding="wsHttpBinding" bindingConfiguration="wsSecureConfiguration"
contract="InternetRailwayTicketSales.TicketSalesInterface.ITicketSales" />
<endpoint address="mex" binding="mexHttpsBinding"
contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="wsSecureConfiguration">
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="defaultBehavior">
<serviceThrottling maxConcurrentInstances="5000" maxConcurrentSessions="5000"/>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
When I press F5 I receive the error message "Contract requires Session, but Binding ‘WSHttpBinding’ doesn’t support it or isn’t configured properly to support it."
I really need the channel which supports SSL and requires session.

You can support sessions by enabling message security:
<binding name="wsHttpSecureSession">
<security>
<message establishSecurityContext="true"/>
</security>
</binding>
If you need to go with transport security you may need to specify a client credential type

Related

The protocol 'https' is not supported

I'm working with a WCF Service hosted in IIS however when i try navigate to the endpoint i receive the error "The protocol 'https' is not supported". It's hosted in IIS 10 locally running Windows 10.
The service is using wsHttpBinding with TransportWithMessageCredential.
Is this error something to do with the SSL certificate or IIS?
I already have a valid localhost certificate in my Local Machine > Personal certificate store.
What I've tried so far
Set the httpsGetUrl attribute to the .svc endpoint.
Checked IIS setting and default protocols is set to "http" which means
both http and https protocols are enabled.
Checked that the Application Pool is using .NET Framework 4.0
Restarted the application pool
I appreciate if someone can assist me.
Here is the current config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="XXX.Zoo.WebServices.ZooServices_3_0"
behaviorConfiguration="ZooServices_3_0_Behavior">
<endpoint
address="https://localhost/Zootest_3_0/ZooServices_3_0.svc"
binding="wsHttpBinding"
bindingConfiguration="ZooServices_3_0_Binding"
contract="XXX.Zoo.WebServices.IZooServices_3_0" />
<endpoint
address="https://localhost/Zootest_3_0/ZooServices_3_0.svc/mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="ZooServices_3_0_Binding"
maxReceivedMessageSize="2147483647"
maxBufferPoolSize="2147483647" >
<readerQuotas
maxDepth="2147483647"
maxStringContentLength="2147483646"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None"
proxyCredentialType="None" realm="" />
<message clientCredentialType="Certificate"
negotiateServiceCredential="true" algorithmSuite="Default"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ZooServices_3_0_Behavior">
<serviceMetadata httpsGetEnabled="true"
httpsGetUrl="https://localhost/Zootest_3_0/ZooServices_3_0.svc" />
<serviceDebug includeExceptionDetailInFaults="False" />
<!--The serviceCredentials behavior defines a service
certificate which is used by the service to authenticate
itself to its clients and to provide message protection. -->
<serviceCredentials>
<serviceCertificate
findValue="localhost"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication
certificateValidationMode="ChainTrust"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
This particular error was resolved by removing the httpsGetUrl attribute from the configuration:
httpsGetUrl="https://localhost/Zootest_3_0/ZooServices_3_0.svc
So the end result looks like this:
<serviceMetadata httpsGetEnabled="true"/>
If you want to enable the https protocol support, you should add the https endpoint which use transport transfer mode to the service. Then we should set up the https protocol site binding in the IIS site binding module.
I have made a demo, wish it is useful to you.
Server end.
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
Web.config
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="mybehavior">
<endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1" bindingConfiguration="https"></endpoint>
<endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1" bindingConfiguration="http"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="https">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None"></transport>
</security>
</binding>
<binding name="http">
<security mode="None">
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="mybehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
IIS.
Here are some links, wish it is useful to you.
WCF Service not hitting from postman over https
https://social.msdn.microsoft.com/Forums/vstudio/en-US/d42fc165-052d-476a-9580-1240b3d0293d/specify-endpoint-in-wcf-webconfig?forum=wcf
Feel free to let me know if there is anything I can help with.

How to add Custom Service Behavior To WCF Configuration

I have a service with ComplexType in the Uri Template Parameter, I have Override the CanConvert() and ConvertStringToValue() methods to the class MyQueryStringConverter.
I need to add that behavior to the web.config file.
Here is the Behavior
public class MyWebHttpBehavior : WebHttpBehavior
{
protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription)
{
return new MyQueryStringConverter();
}
}
Here Is the Configuration File :
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttp"
maxReceivedMessageSize="20000000" >
<security mode="None">
<transport clientCredentialType = "None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="http" port="80" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="Service.Service1" behaviorConfiguration="mexBehaviour">
<endpoint address="" binding="webHttpBinding" contract="Service.IService1" bindingConfiguration="webHttp" behaviorConfiguration="web"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
</endpoint>
</service>
</services>
</system.serviceModel>
Please help how to add that behavior.
First, you must register your behavior, using behaviorExtensions element in your configuration file:
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="MyWebHttpBehavior"
type="FullNameSpace.MyWebHttpBehavior, MyWebHttpBehavior.AssemblyName, Version=1.0.0.0, Culture=neutral" />
</behaviorExtensions>
</extensions>
Where:
"FullNameSpace.MyWebHttpBehavior" is your class with full namespace,
"MyWebHttpBehavior.AssemblyName" is your assembly name with extension
where your class is compiled.
"1.0.0.0" is the version of your assembly
"neutral" is your Culture. Change if any special Culture is required
Secound, declare your behavior:
<behaviors>
<endpointBehaviors>
<behavior name="customMyWebHttpBehavior">
<webHttp/>
<MyWebHttpBehavior/>
</behavior>
</endpointBehaviors>
<behaviors>
Next, add to the binding:
<bindings>
<webHttpBinding>
<binding name="webHttp"
maxReceivedMessageSize="20000000" >
<security mode="None">
<transport clientCredentialType = "None"/>
</security>
</binding>
<MyWebHttpBehavior />
</webHttpBinding>
</bindings>
And finally, set the behavior to your service endpoint:
<endpoint address="" binding="webHttpBinding" contract="Service.IService1" bindingConfiguration="webHttp" behaviorConfiguration="customMyWebHttpBehavior"/>
I've copied this configuration of a service I've developed and changed the names to fit your class/configuration, but check if I did not wrote anything wrong.
I've used this link as base to setup my configuration: Custom Behavior won't register in my web.config
Hope it helps.

Why Creating new session id every time in wsHttpBinding

I am using following configuration to make my service sessionful, but for each request wcf service is responding me with new session id. Why it so, what I need to make it sessionful for that client so that for each request there should be same session id
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttp">
<readerQuotas maxStringContentLength="10240" />
<reliableSession enabled="true" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="wcfservice.serviceclass" behaviorConfiguration="MyFileServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:51/"/>
<add baseAddress="net.tcp://localhost:52/"/>
</baseAddresses>
</host>
<endpoint address="pqr" binding="wsHttpBinding" bindingConfiguration="wsHttp"
name="b" contract="wcfservice.Iservice" />
<endpoint address="pqr" binding="netTcpBinding"
name="c" contract="wcfservice.Iservice" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyFileServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
By default a session is initiated when channel is opened you can read more about it here in this Sessions in WCF
AS the default value of IsInitiating parameter is true each of your calls started a new session. Read more About it here IsInitiating and IsInitiating
So in your Operation contracts
[OperationContract(
IsInitiating=false,
IsTerminating=false
)]
public void MethodOne()
{
return;
}

DotNetOpenAuth and ResourceServer service https configuration

I am trying to configure the DataApi.svc service of the DotNetOpenAuth to call my resources via https using AJAX.
I can call the service and hit the code behind but the OperationContext.Current.ServiceSecurityContext will be not authenticated
In IIS, I have "Anonymous authentication" set to "true".
In Fiddler I can see that the header is sent:
Authorization: Bearer gAAAAMcRmG5vw3LykShq7cNOEGUACBiNtlVGxGYdSVfkkXjR-[truncated]
The interface is decorated like that:
[ServiceContract]
public interface IDataApi {
[OperationContract, WebGet(UriTemplate = "/email", ResponseFormat = WebMessageFormat.Json)]
string GetEmail();
And here is my config:
<bindings>
<wsHttpBinding>
<binding>
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
<webHttpBinding>
<binding>
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="DataApiBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpsGetEnabled="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="DataApiWebBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="DataApiBehavior" name="OAuthResourceServer.DataApi">
<endpoint address="" binding="wsHttpBinding" contract="OAuthResourceServer.Code.IDataApi" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
<endpoint address="web" binding="webHttpBinding" contract="OAuthResourceServer.Code.IDataApi" behaviorConfiguration="DataApiWebBehavior">
</endpoint>
</service>
</services>
Any idea of what can be wrong?
Thanks!
I was missing the
<serviceAuthorizationserviceAuthorizationManagerType="OAuthResourceServer.Code.OAuthAuthorizationManager, OAuthResourceServer" principalPermissionMode="Custom" />
in the service behavior! Solved :)

WCF hosted on SharePoint - Need to enable https

I have a WCF hosted in SharePoint 2013 with two methods GET and SET send JSON data. The WCF worked fine under HTTP servers but now we need to move it to production and run it under SSL where we have a certificate installed on the server.
I made changes to the web.config file but I'm getting error 404 Not Found when I try to call the GET method.
Here is my Web.Config (working on HTTP before the change)
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="WCF.Service" behaviorConfiguration="WCF.ServiceBehavior" >
<endpoint address=""
binding="webHttpBinding"
contract="WCF.IService"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCF.ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior >
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="NoSecurityHttpBinding">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
Here is what I tried to make the code work:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="WCF.Service" behaviorConfiguration="WCF.ServiceBehavior" >
<endpoint address=""
binding="webHttpBinding"
contract="WCF.IService"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCF.ServiceBehavior">
<serviceMetadata **httpsGetEnabled**="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior >
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="NoSecurityHttpBinding">
<security mode="**Transport**">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
Here is my C# Code on the service interface:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "Get/{Code}")]
Stream Get(string Code);
}
Method code
public class Service : IService
{
public Stream Get(string Code)
{
string strOutPut = "";
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json;charset=utf8";
try
{
/// geting data
return new MemoryStream(Encoding.UTF8.GetBytes(strOutPut));
}
catch (Exception e)
{
// error handler
}
}
}
Any Ideas? What am I missing to enable this method on HTTPS as a SharePoint ISAPI hosted service?
You define security for your binding, but you never assign that binding to your endpoint:
<service name="WCF.Service" behaviorConfiguration="WCF.ServiceBehavior" >
<endpoint address=""
binding="webHttpBinding"
contract="WCF.IService" />
</service>
All your service endpoint says is use webHttpBinding - since you didn't specify a configuration for the binding, the defaults are used, and the default transport for webHttpBinding is None.
Use the bindingConfiguration attribute to tell the endpoint which binding configuration to use:
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration="NoSecurityHttpBinding"
contract="WCF.IService" />
I'd suggest changing the name of your configuration to something other than "NoSecurityHttpBinding" if you're adding security to it.
There may be other issues as well, but you won't even get out of the door until you assign the binding configuration to your endpoint.