How to avoid the service certificate? - wcf

"The service certificate is not provided. Specify a service certificate in ServiceCredentials." is what I see when I point my browser to the svc file address
as you can see below, my serviceCredentials section is commented (it's just an example from some book), since I don't want any certificate. But apparently I can't avoid it... what can I do ?
I can't use basicHttpBinding because I want sessions support
my binding:
<wsHttpBinding>
<binding name="BindingToViewer" sendTimeout="00:25:00">
<security mode="Message">
<message clientCredentialType = "None"/>
</security>
</binding>
</wsHttpBinding>
my service:
<service name="SomeNs.Whatever.ServName" behaviorConfiguration="NoPrinPermMode">
<endpoint address="" binding="wsHttpBinding"
bindingConfiguration="BindingToViewer"
contract="SomeNs.Whatever.IMyInterface">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="https://localhost/"/>
</baseAddresses>
</host>
</service>
my service behaviors:
<serviceBehaviors>
<behavior name="NoPrinPermMode">
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
<serviceAuthorization principalPermissionMode="None" />
<!--<serviceCredentials>
<serviceCertificate
findValue = "MyServiceCert"
storeLocation = "LocalMachine"
storeName = "My"
x509FindType = "FindBySubjectName"/>
</serviceCredentials>-->
</behavior>
</serviceBehaviors>

You have configured message security in WSHttpBinding which implies your service must supply a certificate (unless you use windows auth). The question is what kind of security you need if at all?

Do not use https in base address:
<add baseAddress="https://localhost/"/>
use instead:
<add baseAddress="http://localhost/"/>
and remove httpsGetEnabled:
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
to:
<serviceMetadata httpGetEnabled="True" />
and remove identity as you do not need to authentificate service
<identity>
<dns value="localhost" />
</identity>
edit
remove also
<security mode="Message">
<message clientCredentialType = "None"/>
</security>

Related

WCF Ws-Seciurity service configuration

I'm having truble with configuration around my WCF service and WS-Seciurity.
I don't have access to the client side, so far I'm trying to use SoapUI as a client with WS-A adressing, userName, Password and WSS Password Type 'PasswordDigest' options.
I use IIS and https with a simple certificate, .NET 4.7.
I've tried many versions, but without success. I just want to find simplest, working solution to read 'Seciurity' header from SoapUI/client request with WS-Seciurity PasswordDigest options enabled.
The current error with the current config file 'InvalidSecurity' 'An error occurred when verifying security for the message'
<system.serviceModel>
<protocolMapping>
<add scheme="https" binding="wsHttpBinding"/>
</protocolMapping>
<services>
<service name="SoapService" behaviorConfiguration="SoapServiceConf">
<!--<endpoint address="SoapService" binding="wsHttpBinding" contract="MPA.SoapService.References.ServiceReference.SentSOAP" /> -->
<endpoint address="" binding="wsHttpBinding" contract="Interfaces.ISoap" bindingConfiguration="wsHttpBind"/>
<endpoint contract="IMetadataExchange" binding="mexHttpsBinding" address="mex" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding maxReceivedMessageSize="10485760" name="wsHttpBind">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Basic"/>
<message clientCredentialType="UserName" algorithmSuite="Default" establishSecurityContext="false" />
</security>
<reliableSession enabled="false" />
<readerQuotas maxArrayLength="10485760" maxDepth="1024" maxStringContentLength="10485760" />
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="SoapServiceConf">
<serviceCredentials>
<serviceCertificate findValue="soapservice"
storeName="My"
x509FindType="FindByIssuerName" />
</serviceCredentials>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
<behavior name="MyServiceTypeBehaviors" >
<!-- Add the following element to your service behavior configuration. -->
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Thanks.

Not able to access the methods from secure wcf rest service

I have a running wcf rest service hosted on IIS. I have successfully added the .x509 certificates to the client and the server and it works fine.As it is a secure service it is accessed using https The problem I am facing is that I am not able to access any of the methods from the service it keeps throwing 404 error however when I browse the service from IIS using https link it open the WSDL fine but throws 404 error while accessing any of the methods.
Here is my Interface implementation of a method from the service.
[ServiceContract]
public interface IRestDemo
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/DoWork/{name}")]
string DoWork(string name);
}
Here is my configuration file:
<system.serviceModel>
<services>
<service name="RestDemo.RestDemo" behaviorConfiguration="serviceBehavior">
<host>
<baseAddresses>
<add baseAddress="https://localhost/RestDemo/RestDemo.svc" />
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="RestDemo.IRestDemo" behaviorConfiguration="web">
<!--<identity>
<dns value="localhost"/>
</identity>-->
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="RestDemo.IRestDemo" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="web" crossDomainScriptAccessEnabled="true">
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<!--<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust"
trustedStoreLocation="LocalMachine" />
</clientCertificate>
<serviceCertificate findValue="ServerCertificate"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />
</serviceCredentials>-->
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" httpsGetUrl="/RestDemo.svc" />
<!-- 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>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<standardEndpoints>
<webScriptEndpoint>
<standardEndpoint
crossDomainScriptAccessEnabled="true">
</standardEndpoint>
</webScriptEndpoint>
</standardEndpoints>
</system.serviceModel>
Any suggestions would be really appreciated.

WCF service worked with windows authentication, switched to use SSL now it wants anonymous

I have created a WCF service with Windows authentication that worked correctly.
Now I am trying to add SSL. After following the steps, it now seems to be using anonymous authentication, giving this error:
The HTTP request was forbidden with client authentication scheme 'Anonymous'.
Any clues would be appreciated.
We are using IIS 7.5 on Windows Server 2008 R2 and .Net version 4
The config file that worked correctly had this service model (server side):
<system.serviceModel>
<bindings />
<client />
<services>
<service name="WCFServiceTest.Service1" behaviorConfiguration="WCFServiceBehavior">
<endpoint address="" binding="wsHttpBinding" contract="WCFServiceTest.WCFService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFServiceBehavior">
<serviceMetadata httpGetEnabled="True" policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
This is the changed configuration
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="TransportWsSecurity">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client />
<services>
<service name="WCFServiceTest.Service1" behaviorConfiguration="WCFServiceBehavior">
<endpoint address="" binding="wsHttpsBinding"
bindingConfiguration="TransportWsSecurity"
contract="WCFServiceTest.WCFService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
<host>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFServiceBehavior">
<serviceMetadata httpsGetEnabled="True" policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
This is the code that calls the service. It never gets to the IgnoreCertificateErrorHandler which just returns true:
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(IgnoreCertificateErrorHandler);
WCFService1Client client = new WCFService1Client();
client.ClientCredentials.Windows.ClientCredential.UserName = Utility1.GetConfig("RemoteLogin");
client.ClientCredentials.Windows.ClientCredential.Password = Utility1.GetConfig("RemotePassword");
try
{
result = client.SendUpdatesFromLocation(temp);
}
catch (FaultException<WCFProcessFault> ex)
{
string op = ex.Detail.Operation;
string err = ex.Detail.Notes;
}
finally
{
client.Close();
}
WCFService1Client client = new WCFService1Client();
client.ClientCredentials.Windows.ClientCredential.UserName = Utility1.GetConfig("RemoteLogin");
client.ClientCredentials.Windows.ClientCredential.Password = Utility1.GetConfig("RemotePassword");
try
{
result = client.SendUpdatesFromLocation(temp);
}
catch (FaultException<WCFProcessFault> ex)
{
string op = ex.Detail.Operation;
string err = ex.Detail.Notes;
}
finally
{
client.Close();
}
<bindings>
<wsHttpBinding>
<binding name="TransportWsSecurity">
<security mode="Transport">
<transport clientCredentialType="Ntlm"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
Try the above changes. This will use Ntlm rather than Negotiate (Kerberos) for auth. It is very very likely you haven't setup your server for Kerberos auth.

IIS 7.5 Wcf https WSDL always returns blank (bad request)

Everything else works fine, I can make SOAP and RESTful calls w/o issue via https. But WSDL always returns blank (bad request). HTTP returns WSDL fine.
Trace log inner exception reports:
The body of the message cannot be read because it is empty.
serviceMetaData tag is set:
<serviceMetadata
httpGetEnabled="true"
policyVersion="Policy15"
httpsGetEnabled="true" />
web.Config sections
Binding:
<bindings>
<basicHttpBinding>
<binding name="soapBinding">
<security mode="None">
</security>
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="webBinding">
<security mode="None">
</security>
</binding>
</webHttpBinding>
</bindings>
You will immediately notice security mode="None"
Via ServiceHostFactory I see the mode to transport as:
ServiceHost serviceHost = new ServiceHost(service.GetType(), baseAddresses);
if (ExposeSSL(baseAddresses[0]))
{
foreach (var endpoint in serviceHost.Description.Endpoints)
{
if (endpoint.Binding is WebHttpBinding)
{
((WebHttpBinding)endpoint.Binding).Security.Mode = WebHttpSecurityMode.Transport;
endpoint.Address = new EndpointAddress(baseAddresses[0].ToString().Replace("http", "https"));
}
if (endpoint.Binding is BasicHttpBinding)
{
((BasicHttpBinding)endpoint.Binding).Security.Mode = BasicHttpSecurityMode.Transport;
endpoint.Address = new EndpointAddress(baseAddresses[0].ToString().Replace("http", "https"));
}
}
Services configuration:
<service name="xxxx.Wcf.AdminJsonService" behaviorConfiguration="DefaultBehaviour">
<host>
<baseAddresses>
<!-- note, choose an available port-->
<add baseAddress="http://localhost:62701/json"/>
</baseAddresses>
</host>
<!-- Service Endpoints -->
<endpoint address="" binding="webHttpBinding" bindingConfiguration="webBinding" behaviorConfiguration="jsonBehavior" bindingNamespace="https://www.xxxx/WebService4/AdminJsonService" contract="xxxx.Wcf.IAdminJsonService"/>
</service>
<service name="xxxx.Wcf.AdminXmlService" behaviorConfiguration="DefaultBehaviour">
<host>
<baseAddresses>
<!-- note, choose an available port-->
<add baseAddress="http://localhost:62701/xml"/>
</baseAddresses>
</host>
<!-- Service Endpoints -->
<endpoint address="" binding="webHttpBinding" bindingConfiguration="webBinding" behaviorConfiguration="poxBehavior" bindingNamespace="https://www.xxx/WebService4/AdminXmlService" contract="xxxx.Wcf.IAdminXmlService"/>
</service>
<service name="xxxx.Wcf.AdminSoapService" behaviorConfiguration="DefaultBehaviour">
<!-- Service Endpoints -->
<endpoint binding="basicHttpBinding" behaviorConfiguration="soapBehavior" bindingNamespace="https://www.example.com/WebService4/AdminSoapService" contract="xxxx.Wcf.IAdminSoapService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
Endpoint behaviours
<!-- SOAP -->
<behavior name="soapBehavior">
</behavior>
<!-- JSON -->
<behavior name="jsonBehavior">
<webHttp/>
</behavior>
<!-- POX -->
<behavior name="poxBehavior">
<webHttp/>
</behavior>
Service Behaviours
<behavior name="ErrorBehaviour">
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<behavior name="DefaultBehaviour">
<NiceErrorHandler/>
<!-- 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"/>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata
httpGetEnabled="true"
policyVersion="Policy15"
httpsGetEnabled="true" />
</behavior>
Also have
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
Anyone have idea's why this may be occurring?
Did you try turning off one of the other endpoints? In my case WCF didn't work until I disabled one of the endpoints. It didn't matter which one I disabled. The others would work.
<services>
<service name="GTW.TrendToolService" behaviorConfiguration="MyServiceBehavior">
<!--<endpoint name="rest" address="" binding="webHttpBinding" contract="TT.ITrendtoolService" behaviorConfiguration="restBehavior"/>-->
<endpoint name="json" address="json" binding="webHttpBinding" behaviorConfiguration="jsonBehavior" contract="GTW.IAqvService" />
<endpoint name="xml" address="xml" binding="webHttpBinding" behaviorConfiguration="restBehavior" contract="GTW.IAqvService" />
<!--<endpoint name="mex" address="mex" binding="mexHttpBinding" contract="GTW.IAqvService" />
<endpoint name="soap" address="soap" binding="basicHttpBinding" contract="GTW.IAqvService" />-->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="restBehavior">
<webHttp />
</behavior>
<behavior name="jsonBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
I believe your issue is going to be related to your service behaviors section. Specifically you told .net to publish your WSDL in HTTP but not HTTPS. Try the following
<behavior name="DefaultBehaviour">
<NiceErrorHandler/>
<!-- 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"/>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata
httpGetEnabled="true"
httpsGetEnabled="true"
policyVersion="Policy15"
httpsGetEnabled="true" />
</behavior>
Note the extra line in the serviceMetadata referring to httpsGet as opposed to http.
I will assume that https is enabled on both the bindings and in your application given that you can see the http WSDL rather than some mumble jumbo about not being able to find bindings or something...
When you are doing the Transport encryption you have to add the s to your base address protocol ex: < add baseAddress="https://localhost:62701/xml"/> or < add baseAddress="http://localhost:62701/json"/>

Server side WCF (.svc) service stops working after exception

I'm using a duplex ReliableSecureProfile in WCF and the server will stop listening to new requests if an exception occurs on any client.
How can I make the server more resilient to failures that happen to any single client? Everything works again if I restart the server or redeploy
My client code looks like this:
CustomBinding rspBinding = new CustomBinding();
rspBinding.Elements.Add(new ReliableSessionBindingElement());
rspBinding.Elements.Add(new MakeConnectionBindingElement());
rspBinding.Elements.Add(new TextMessageEncodingBindingElement());
rspBinding.Elements.Add(new HttpTransportBindingElement());
DuplexChannelFactory<IProcessDataDuplex> channelFactory =
new DuplexChannelFactory<IProcessDataDuplex>
(new CallbackHandler(), rspBinding, serviceAddress);
//
// The problem always occurs on this line.
//
reusableSW = new LC.Utils.WCF.ServiceWrapper<IProcessDataDuplex>(channelFactory);
My web.config looks like this:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="rspServiceBehavior">
<serviceMetadata httpGetEnabled="true" policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="http" port="80" />
<add scheme="https" port="443" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<!-- Reliable Secure Profile -->
<binding name="rspBinding">
<reliableSession />
<MakeConnectionBindingElement/>
<textMessageEncoding />
<httpTransport />
</binding>
</customBinding>
<netTcpBinding>
<binding portSharingEnabled="true" >
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<extensions>
<bindingElementExtensions>
<!-- Reliable Secure Profile -->
<add name="MakeConnectionBindingElement" type="Microsoft.Samples.ReliableSecureProfile.MakeConnectionElement, Microsoft.Samples.ReliableSecureProfile.MakeConnectionChannel" />
</bindingElementExtensions>
</extensions>
<services>
<!-- Reliable Secure Profile -->
<service behaviorConfiguration="rspServiceBehavior" name="Microsoft.Samples.ReliableSecureProfile.RSPService">
<endpoint binding="customBinding" bindingConfiguration="rspBinding"
contract="Microsoft.Samples.ReliableSecureProfile.IProcessDataDuplex"
listenUriMode="Explicit">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
</host>
</service>
<!--<service name="WcfTcpTest.Service1" >
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:1337/Service1/" />
</baseAddresses>
</host>
<endpoint address="" binding="netTcpBinding" contract="WcfTcpTest.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>-->
</services>
<protocolMapping>
<clear/>
<!-- removes all defaults which you may or may not want. -->
<!-- If not, use <remove scheme="http" /> -->
<add scheme="http" binding="customBinding" bindingConfiguration="rspBinding"/>
</protocolMapping>
<serviceHostingEnvironment
aspNetCompatibilityEnabled="false"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
I can't reproduce this issue anymore (where the server simply stops responding). I think the issue is related to VS2010's desire to catch handled exceptions and stop all threads as explained here:
Getting an Unhandled Exception in VS2010 debugger even though the exception IS handled