Changing wcf service from Http to https makes it unreachable - c#

I have had to change a wcf service I had running on console application to https due to an issue with "mixed content blocking" in firefox.
This is the config:
<services>
<service name="ServiceHost.Services.BiometricCaptureService" behaviorConfiguration="Default">
<endpoint address="rest" behaviorConfiguration="CorsBehavior" binding="webHttpBinding" bindingConfiguration="httpsBinding" contract="ServiceHost.IServices.IBiometricCaptureService"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="https://localhost:8502/biometrics/biometricscaptureservice.svc"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="CorsBehavior">
<webHttp/>
<crossOriginResourceSharingBehavior/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="crossOriginResourceSharingBehavior" type="ServiceHost.Utility.CORSBehaviorExtensionElement, ServiceHost, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<bindings>
<webHttpBinding>
<binding name="httpsBinding" maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
</security>
<readerQuotas maxStringContentLength="2147483647" />
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
Starting the service does not throw any errors with this configuration but I cannot hit on the endpoint any more.
The only error I could get was this: "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."
Can anyone see any issues with this?

I don't see how your service will find the encryption certificate.
You should have something like this:
<behaviors>
<serviceBehaviors>
<behavior name="mySvcBehavior">
<serviceCredentials>
<serviceCertificate findValue="xxxxxx" x509FindType="FindByThumbprint" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
This is a pretty decent step-by-step guide to setting up HTTPS on a WCF site. http://robbincremers.me/2011/12/27/wcf-transport-security-and-client-certificate-authentication-with-self-signed-certificates/

Related

WCF - HTTPS - Transport security works but message security throws exception on application startup

I have a WCF self hosted server (a console application which registers the wcf contract with castle ioc container AsWcfService). I need it to work securely over https.
When I configure the server to use wsHttpBinding with security mode=Transport and clientCredentialsType=None, everthing works fine.
The configurations looks as follows:
Transport Security Configuration
<behaviors>
<serviceBehaviors>
<behavior name="secureBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" httpsHelpPageEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="secureBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" sendTimeout="01:00:00">
<security mode="Transport" >
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="service" behaviorConfiguration="secureBehavior">
<endpoint binding="wsHttpBinding" bindingConfiguration="secureBinding" contract="Contract.Service" />
<host>
<baseAddresses>
<add baseAddress="https://domain-name:port-number/"/>
</baseAddresses>
</host>
</service>
</services>
The above works fine.
Message Security Configuration
<behaviors>
<serviceBehaviors>
<behavior name="secureBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" httpsHelpPageEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="secureBinding" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" sendTimeout="01:00:00">
<security mode="Message" >
<message clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="service" behaviorConfiguration="secureBehavior">
<endpoint binding="wsHttpBinding" bindingConfiguration="secureBinding" contract="Contract.Service" />
<host>
<baseAddresses>
<add baseAddress="https://domain-name:port-number/"/>
</baseAddresses>
</host>
</service>
</services>
With message security configuration, however, when I try to start the server I get the following exception:
Could not find a base address that matches scheme http for the
endpoint with binding WSHttpBinding. Registered base address schemes
are [https]. System.InvalidOperationException: Could not find a base
address that matches scheme http for the endpoint with binding
WSHttpBinding. Registered base address schemes are [https].
I can't find the reason for this error anywhere I look.
An explanation would be highly appreciated.

WCF Configuration Error: There was no endpoint listening at

I am trying to use a WCF service (I didn't write) from a WebAPI and am getting the dreaded 'There was no endpoint listening at...' error. The interesting thing is that the service has a test ASPX page that uses it without error. So I copied the client portion of the config and added that to my API.
Client:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IAuthenticationService" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport" />
</binding>
</basicHttpBinding>
<customBinding>
<binding name="CustomBinding_ILockboxServiceV1">
<security authenticationMode="UserNameOverTransport" includeTimestamp="true">
<secureConversationBootstrap />
</security>
<textMessageEncoding messageVersion="Default" writeEncoding="utf-8" />
<httpsTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://devsandbox2.imagebankingsystem.com/LockboxRemote.Web/ws/LockboxServiceV1.svc"
binding="customBinding" bindingConfiguration="CustomBinding_ILockboxServiceV1"
contract="PaymentGateway.ILockboxServiceV1" name="CustomBinding_ILockboxServiceV1" />
<endpoint address="https://devsandbox2.imagebankingsystem.com/LockboxRemote.Web/ws/AuthenticationService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAuthenticationService"
contract="PaymentGatewayAuthentication.IAuthenticationService" name="BasicHttpBinding_IAuthenticationService" />
</client>
</system.serviceModel>
Server:
<services>
<service name="LockboxRemote.Web.ws.LockboxServiceV1" behaviorConfiguration="ServiceBehavior">
<endpoint behaviorConfiguration="MexFlatWSDLBehavior" address="" binding="customBinding" contract="LockboxRemote.Web.ws.ILockboxServiceV1" bindingConfiguration="myConfig" bindingNamespace="https://devsandbox2.imagebankingsystem.com/LockboxRemoteGateway/ws/LockboxServiceV1"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="MexFlatWSDLBehavior">
<FlatWSDL />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceAuthorization principalPermissionMode="Custom">
<authorizationPolicies>
<add policyType="LockboxRemote.Web.AuthorizationPolicy, LockboxRemote.Web" />
</authorizationPolicies>
</serviceAuthorization>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="LockboxRemote.Web.CustomValidator,LockboxRemote.Web" />
</serviceCredentials>
<serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />
</behavior>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceAuthorization principalPermissionMode="None"/>
<serviceSecurityAudit auditLogLocation="Application" serviceAuthorizationAuditLevel="Failure" messageAuthenticationAuditLevel="Failure" suppressAuditFailure="true" />
</behavior>
</serviceBehaviors>
</behaviors>
May or may not be important but my WebAPI is on the same server but in a different virtual directory.
Thanks in advance.
Turns out nothing was wrong with it. The error was caused by the firewall which was preventing the server from talking to itself through the external address. Added a hostsfile entry to get around that.

How to pass Username Credential WCF through Castle Windsor

I have a problem to pass username and password through Castle Windsor register by using custom WCF authentication.
I have a Web service configuration like below :
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsSecureBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="defaultProfile" name="GS1.CSSM.XMLGenerate.WebService.Implementation.XMLGenerateService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsSecureBinding" name="wsSecureService" contract="GS1.CSSM.XMLGenerate.WebService.Interface.IXMLGenerateService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="defaultProfile">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="GS1.CSSM.XMLGenerate.WebService.ServiceAuthenticator, GS1.CSSM.XMLGenerate.WebService"/>
</serviceCredentials>
</behavior>
<behavior name="noAuthentication">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
This is the Container Setup :
var container = new WindsorContainer();
container.AddFacility()
.Register(
Component.For<IXMLGenerateService>()
.ImplementedBy<XMLGenerateServiceClient>()
.AsWcfClient(
new DefaultClientModel
{
Endpoint =
WcfEndpoint.FromConfiguration("wsSecureService")
}.Credentials(new UserNameCredentials("zul", "password"))));
And this is client config file :
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsSecureService">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://localhost:44302/Service/XMLGenerateService.svc" binding="wsHttpBinding" bindingConfiguration="wsSecureService" contract="XMLGenerateService.IXMLGenerateService" name="wsSecureService" />
</client>
</system.serviceModel>
I got this error "Additional information: The username is not provided. Specify username in ClientCredentials." once I tried to call method from the service.
Any ideas?
I will answer it by myself :)
here it is how i resolved that issue
container.Kernel.AddFacility<WcfFacility>()
.Register(Component.For<IXMLGenerateService>()
.AsWcfClient(new DefaultClientModel
{
Endpoint = WcfEndpoint.FromConfiguration("wsSecureService")
}.Credentials(new UserNameCredentials("zul", "password"))));
_smXMLGenerateService = container.Resolve<IXMLGenerateService>();
Hopefully, it can help anyone with the same issue.

WCF service is working on dev server but on production it is not woking

I have a .net client and I am consuming the WCF service and able to do that sucessfully. but when i try to post that on our production I am not able to consume the same service. Below is my web.config :
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<useRequestHeadersForMetadataAddress></useRequestHeadersForMetadataAddress>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="TestProject.Implementations.AuthenticateUser,TestProject"/>
<serviceCertificate findValue="localhost" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="TestProject.Implementations.ServiceCustom" behaviorConfiguration="MyBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="SampleServiceBinding" contract="TestProject.Interfaces.IServiceCustom"></endpoint>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"></endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="SampleServiceBinding">
<security mode ="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
and also I want to make my service HTTPS enabled.
I get below errormessage:
There was no endpoint listening at http://url.com that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
This error clearly suggest that the WCF service you are trying to access is not clearly hosted, or the address you are using to connect to is not pointing to the service, make sure by using the address in a browser you are able to access that service.
If you are able to access the service , check your client application web.config and find out the end point details for that service. If the endpoint url is mismatched you may get this error.
I fixed the error and below is the web config code:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior">
<useRequestHeadersForMetadataAddress></useRequestHeadersForMetadataAddress>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="TestProject.Implementations.AuthenticateUser,TestProject"/>
<serviceCertificate findValue="localhost" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="TestProject.Implementations.Test" behaviorConfiguration="MyBehavior">
<endpoint address="http://rul" binding="wsHttpBinding" bindingConfiguration="SampleServiceBinding" contract="TestProject.Interfaces.Test"></endpoint>
<endpoint address="https:url" binding="wsHttpBinding" bindingConfiguration="SampleServiceBindingHttps" contract="TestProject.Interfaces.ITest"></endpoint>
<endpoint contract="IMetadataExchange" binding="mexHttpsBinding" address="mex"></endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="SampleServiceBinding">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
<binding name="SampleServiceBindingHttps">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
I changed the security mode to TransportWithMessageCredential mode and change few config like binding = "mexHttpsBinding"

how to replace Machine Name with Domain name in WCF Service wsdl link

wasnt sure quite what to name the question but the problem is as follows:
I am deploying a WCF service on IIS 6 which is to be consumed by an external source.
the box that it is on is externally hosted but has a DC so is effectively on my network ('mydomain'), internally it's called 'prod' say.
the service need to run over SSL so we got an SSL cert for the domain the service will respond to: service.oursite.com lets say
DNS has all filtered through and I can indeed hit the service on
https://service.oursite.com/service.svc
and it kicks out the little svcutil link .
the problem is that the address that the link points to is not
https://service.oursite.com/service.svc?wsdl as I would hope
it is instead
https://prod.mydomain.com/service.svc?wsdl
so of course the SSL bails as the cert is not for that
and if i click through to the wsdl all the schemaLocation links are wrong, again pointing to the internal rather than external name
question is:
why is it doing that?
and
how do i stop it doing that?
is it a matter of adding something in the config? (please say yes :))
any help as ever most gratefully received
if it helps here is the config
<services>
<service name="CBBookingService.CBBookingService" behaviorConfiguration="CBBookingService.CBBookingServiceBehavior">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="TransportSecurity" contract="CBBookingService.ICBBookingService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="BasicSecurity" maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
<binding name="TransportSecurity" maxReceivedMessageSize="2147483647">
<!--https-->
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CBBookingService.CBBookingServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
You can use the <useRequestHeadersForMetadataAddress> service behavior, and you should get the behavior you want:
<behaviors>
<serviceBehaviors>
<behavior name="CBBookingService.CBBookingServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<useRequestHeadersForMetadataAddress />
</behavior>
</serviceBehaviors>
</behaviors>
You can change it in your configuration.
<serviceMetadata httpGetEnabled="true"
externalMetadataLocation="https://service.oursite.com/service.svc?wsdl"/>
or use https://stackoverflow.com/a/14592767/2012977 for asp.net v4 or later.
thanks for the answers
unfortunately I am using .net 3.5 so the answers below do not work
I ended up doing this
<system.serviceModel>
<services>
<service name="CBBookingService.CBBookingService" behaviorConfiguration="CBBookingService.CBBookingServiceBehavior">
<endpoint address="https://service.oursite.com/CBBookingService.svc" binding="basicHttpBinding" bindingConfiguration="TransportSecurity" contract="CBBookingService.ICBBookingService" name="SSL" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="BasicSecurity" maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
<binding name="TransportSecurity" maxReceivedMessageSize="2147483647">
<!--https-->
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="CBBookingService.CBBookingServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpsGetUrl="https://service.oursite.com/CBBookingService.svc/SSL" />
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
</serviceHostingEnvironment>
</system.serviceModel>

Categories