Getting HTTPS to Work with WCF and a Windows Service - windows

I tried updating the App.config files for the client and service for the MS sample applications in WF_WCF_Samples\WCF\Basic\Services\Hosting\WindowsService\CS\WindowsService.sln so that secure bindings were used but when the client makes the call to the service method an exception is thrown
"An error occurred while making the HTTP request to https:// .... /servicemodelsamples/service. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server."
Inner exception "The underlying connection was closed: An unexpected error occurred on a send"
As far as I can see both the server and client configs match and use Transport security mode and the mex endpoint now uses mexHttpsBinding rather than mexHttpBinding with the service behaviour appropriately enabled.
Can someone tell me what is missing or incorrect as I have tried numerous tweaks with no success?
Thanks
The server and client configs are
<?xml version="1.0"?>
<!--Copyright (c) Microsoft Corporation. All Rights Reserved.-->
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.Samples.WindowsService.WcfCalculatorService">
<host>
<baseAddresses>
<add baseAddress="https://localhost:8000/ServiceModelSamples/service"/>
</baseAddresses>
</host>
<!-- This endpoint is exposed at the base address provided by host: https://localhost:8000/ServiceModelSamples/service -->
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="https" contract="Microsoft.Samples.WindowsService.ICalculator"/>
<!-- The mex endpoint is exposed at https://localhost:8000/ServiceModelSamples/service/mex -->
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<!-- Configure BasicHttp binding with Transport security mode and clientCredentialType as None -->
<binding name="https">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<!-- For debugging purposes set the includeExceptionDetailInFaults attribute to true -->
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
and
<?xml version="1.0"?>
<!--Copyright (c) Microsoft Corporation. All Rights Reserved.-->
<configuration>
<system.serviceModel>
<client>
<endpoint name="" address="https://localhost:8000/servicemodelsamples/service" binding="basicHttpBinding" bindingConfiguration="Binding1" contract="Microsoft.Samples.WindowsService.ICalculator"/>
</client>
<bindings>
<basicHttpBinding>
<!-- Configure BasicHttp binding with Transport security mode and clientCredentialType as None -->
<binding name="Binding1">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

mex cant be https
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
change to
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>

Related

WCF Service hosting in IIS and accessing it using Static IP

I am hosting a WCF service in IIS , it works fine on single system, but when I am trying to access it using remote machine(my system has static ip), it ask me username and password,
when I provide that using computer credentials , it doesn't accept it
Picture 1 shows that figure,
<?xml version="1.0"?>
<bindings>
<basicHttpBinding>
<binding name="Service1Soap">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="None"
realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WCF_Static.WCF_Service" behaviorConfiguration="maxBehaviour">
<endpoint address="staticip" binding="basicHttpBinding" contract="WCF_Static.IWCF_Service" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost/8080"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="maxBehaviour">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
On Client side proxy I am using
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IWCF_Service" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://123.123.123.123/Alias/Service.svc/staticip"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IWCF_Service"
contract="ServiceReference1.IWCF_Service" name="BasicHttpBinding_IWCF_Service" />
</client>
</system.serviceModel>
</configuration>
Refereed links here
Thanks,
Found ! ! :)
deploy service as http://localhost/abc/Service1.svc?wsdl or (http://127.0.0.1/abc/Service1.svc?wsdl) in IIS, on client side add service reference as http://localhost/abc/Service1.svc?wsdl or http://127.0.0.1/abc/Service1.svc?wsdl ,
but in appconfig on client side
change the localhost or 127.0.0.1 to your ip address where actual WCF service is running.
in endpoint like this
endpoint address="http://123.123.123.123/max/Service.svc/static"

WCF Service, the type provided as the service attribute values...could not be found

I have this issue a long time ago and just cannot recall how to resolve it or perphaps its something new. I created a WCF service which I will later use in web application that calls the WCF service amongst others from a remote location. Right now I am trying to host in IIS and even tried the WCFTestClient. The error I get when I try to browse to the service; is the following:
The type MyService.Service1 provided as the Service attribute
value in the ServiceHost directive, or provided in the
configuration element system.serviceModel/serviceHostingEnvironment/
serviceActivations could not be found.
I figured its probably my web.config file but I cannot see whats wrong:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings>
<webHttpBinding>
<binding name="webHttpBinding" crossDomainScriptAccessEnabled="false" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="webHttpBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="webHttpBehavior" name="WcfInstanceRules2.Service1">
<endpoint address=""
binding="webHttpBinding"
contract="WcfRules2.IServiceS" behaviorConfiguration="web"/>
<endpoint address="mex"
binding="webHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
I would like this to be eventually a rest service delivering data in json format.
Check your .svc file and see what service it's referencing - probably MyService.Service1, which doesn't exist in your config. It looks like it should be referencing WcfInstanceRules2.Service1.

Hosting the same WCF Service in IIS and in Windows Service

I am trying to decide on an architecture for a change in my web service. I need to make a WCF service. I want to make only one service and then host it either in the IIS or in a Windows service. Is this even possible, making this kind of reuse of a WCF Service? How would I go about doing this? The scenario is that some of our customers do not have access to start a Windows service but can install a WCF in the IIS.
Thank you in advance.
A WCF service is simply an assembly that abides by the WCF hosting interface and then provides a client interface that allows it to be accessed.
Hosting a WCF service occurs equally in IIS, Windows service, WinForm application, or a console application. It truly doesn't matter.
The client interface remains unchanged, although how the interface is exposed might change depending on hosting scenario. For example, you'll probably use one the http bindings in the IIS case, but might use TCP binding for Windows services. These bindings can be defined in the config file, so the code doesn't necessarily have to change to accommodate being hosted one way or the other.
In short, creating the WCF service should be independent of how it will eventually be hosted. For ease of maintenance on your part, though, I'd pick one or the other - Windows service or IIS.
you could have a windows service host the WCF and expose all end points on it..Http,TCP..
Windows service is better than IIS because IIS is a process in itself and then we place upon it a VD to host our website/WCF.As for the Windows Service,it will be one dedicated thread catering only to the WCF.I am sharing the app.config of windows service (details changed) to show how we have hosted WCF...hope it helps..
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Off" propagateActivity="true" >
<listeners>
<add name="SERVICE_MONITOR" type="System.Diagnostics.XmlWriterTraceListener"
initializeData="MyApp_MONITOR.svclog" />
</listeners>
</source>
<source name="MyApp_TRACE" switchValue="All" >
<listeners>
<add name="MyApp_TRACE_LISTENER" type="System.Diagnostics.XmlWriterTraceListener"
initializeData="MyApp_TRACE.svclog" />
</listeners>
</source>
</sources>
<trace autoflush="true" />
</system.diagnostics>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="OverAllServiceBehavior">
<serviceSecurityAudit
auditLogLocation="Application"
serviceAuthorizationAuditLevel="Failure"
messageAuthenticationAuditLevel="Failure"
suppressAuditFailure="true" />
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
<serviceThrottling maxConcurrentCalls="10000" maxConcurrentSessions="10000"
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="MyAppHost.Authenticate, MyAppHost"/>
<serviceCertificate findValue="MyApp_MESSAGE" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication
certificateValidationMode="PeerTrust"
trustedStoreLocation="LocalMachine" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="OverAllEndPointBehavior" />
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="ServiceBasicHttpEndPointBinding" closeTimeout="00:00:59"
openTimeout="00:00:59"
messageEncoding="Text"
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</basicHttpBinding>
<wsHttpBinding>
<binding name="ServiceWSHttpEndPointBinding" closeTimeout="00:00:59"
openTimeout="00:00:59"
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
<netTcpBinding>
<binding name="ServiceTCPEndPointBinding" maxBufferSize="2147483647"
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport
clientCredentialType="Certificate"
protectionLevel="EncryptAndSign" />
<message clientCredentialType="UserName" algorithmSuite="TripleDes"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service behaviorConfiguration="OverAllServiceBehavior"
name="MiddleWare.ServiceClasses.ServiceClass">
<host>
<baseAddresses>
<add baseAddress="net.tcp://127.0.0.1:15010/ServiceTCPEndPointMEX"/>
<add baseAddress="http://127.0.0.1:15020/ServiceHttpEndPointMEX"/>
<add baseAddress="https://127.0.0.1:15030/ServiceWSHttpEndPointMEX"/>
</baseAddresses>
</host>
<endpoint address="net.tcp://127.0.0.1:15040/ServiceTCPEndPoint"
contract="MiddleWare.ServiceContracts.IServiceContract" />
<endpoint address="http://127.0.0.1:15050/ServiceBasicHttpEndPoint"
contract="MiddleWare.ServiceContracts.IServiceContract"/>
<endpoint address="https://127.0.0.1:15060/ServiceWSHttpEndPoint"
contract="MiddleWare.ServiceContracts.IServiceContract"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
<appSettings>
<add key="UserName" value="USER"/>
<add key="Password" value="PASSWORD"/>
</appSettings>
</configuration>

WCF Hosted as Service

I have a VB.NET WCF service hosted as a Window Service. I was able to create an install package, install the service to my machine, and start the service manually from Services in Administrative Tools.
Now when I try to reference the service in my test console application (Address: http://localhost:8080/), I get the following error:
There was an error downloading 'http://localhost:8080'.`
Unable to connect to the remote
server No connection could be made
because the target machine actively
refused it 127.0.0.1:8080`
Metadata contains a reference that
cannot be resolved:
'http://localhost:8080/'. Could not
connect to http://localhost:8080/. TCP
error code 10061: No connection could
be made because the target machine
actively refused it 127.0.0.1:8080.
Unable to connect to the remote server
No connection could be made because
the target machine actively refused it
127.0.0.1:8080 If the service is defined in the current solution, try
building the solution and adding the
service reference again.
Not sure what I can do about this. Any ideas???
Thanks,
Jason.
Here's the code from app.config inside my service:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<sources>
<!-- This section defines the logging configuration for My.Application.Log -->
<source name="DefaultSource" switchName="DefaultSwitch">
<listeners>
<add name="FileLog"/>
<!-- Uncomment the below section to write to the Application Event Log -->
<!--<add name="EventLog"/>-->
</listeners>
</source>
</sources>
<switches>
<add name="DefaultSwitch" value="Information" />
</switches>
<sharedListeners>
<add name="FileLog"
type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
initializeData="FileLogWriter"/>
</sharedListeners>
</system.diagnostics>
<system.serviceModel>
<services>
<service name="ExStreamWCF.Service1"
behaviorConfiguration="ExStreamWCF.Service1Behavior">
<!-- Service Endpoints -->
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8080/Design_Time_Addresses/JasonsService/Service/" />
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="ExStreamWCF.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ExStreamWCF.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
If anyone needs more from me please let me know!
Not sure if it's really an issue - but on a production server, I would never use localhost as my base address.
So can you try to change:
<service name="ExStreamWCF.Service1"
behaviorConfiguration="ExStreamWCF.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8080/Design_Time_Addresses/JasonsService/Service/" />
</baseAddresses>
</host>
to
<service name="ExStreamWCF.Service1"
behaviorConfiguration="ExStreamWCF.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://YourServerName:8080/Design_Time_Addresses/JasonsService/Service/" />
</baseAddresses>
</host>
Does that make any difference when calling into the service??

WCF service under https environment

I've created and tested WCF service, everything works fine.
When I deployed to TEST environment and tried to open https://my.site/myapp/EnrollmentService.svc I've got the error message:
Could not find a base address that
matches scheme http for the endpoint
with binding
MetadataExchangeHttpBinding.
Registered base address schemes are
[https].
Internet showed me that I need to add some more configuration options:
http://www.codeproject.com/KB/WCF/7stepsWCF.aspx
I've added some settings to service web.config file. Now it looks like in the following way:
<system.serviceModel>
<services>
<service name="McActivationApp.EnrollmentService" behaviorConfiguration="McActivationApp.EnrollmentServicBehavior">
<endpoint
address="https://my.site/myapp/EnrollmentService.svc"
binding="basicHttpBinding"
bindingConfiguration="TransportSecurity"
contract="McActivationApp.IEnrollmentService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="McActivationApp.IEnrollmentService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="McActivationApp.EnrollmentServicBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Actually, I've added "bindings" section and specified it for my endpoint.
But this changed nothing...
Please advise, what I need to do. Thanks a lot!
P.S. Are there any differences in WCF service consuming from https and http resources?
When you want to expose your service only over HTTPS (site does not support HTTP at all) you can't use anything that is dependent on HTTP. Your current configuration exposes help page on HTTP and also mex endpoing (with wrong contract) on HTTP. So try this:
<system.serviceModel>
<services>
<service name="McActivationApp.EnrollmentService" behaviorConfiguration="McActivationApp.EnrollmentServicBehavior">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="TransportSecurity" contract="McActivationApp.IEnrollmentService"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="McActivationApp.EnrollmentServicBehavior">
<serviceMetadata httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
You have got http metadata endpoint that should be changed to https as below.
<serviceMetadata httpsGetEnabled="True"/>
Also if not necessary you should remove the mex and https metadata endpoint from production as a best practice.
To fix the problem by allowing HTTP, you need to add a http binding in IIS:
Navigate to your site in IIS
Click 'Bindings...' in the Actions panel on the right.
Click 'Add'
Select 'http' and OK out.
Alternatively, you can prevent the problem by either deleting the line, or changing:
<serviceMetadata httpGetEnabled="True"/>
to:
<serviceMetadata httpsGetEnabled="True"/>

Resources