WCF service calls works properly in Intranet, but not in internet - wcf

I've been working with silverlight application for over a month now, and have stumbled upon a weird issue.
I have a WCF service running in IIS, accessible from the URL :
https://xyztestname.com/service1.svc
I am able to consume this in visual studio and when deployed from visual studio, am able to get proper call backs from WCF service and everything works fine.
When i deploy the package files in to the same folder as the Service1.svc in IIS, the WCF service is not hitting properly.
Please help me resolve this issue :(! Here is my web.config file.
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<customErrors mode="Off"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="InformationService.Service1">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding"
name="BasicHttpEndpoint" contract="InformationService.IService1">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
I dont know where i am going wrong. But the same Virtual folder when accessed through intranet works fine, but doesn't work when accessed through internet :( Please help.
Edit:
After checking into the client config, i found out that Visual studio automatically resolved the URL into an intranet URL. When i changed back to the internet URL, i am getting an exception thrown.
n error occurred while trying to make a request to URI 'https://xyztestname.com/Service1.svc'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. This error may also be caused by using internal types in the web service proxy without using the InternalsVisibleToAttribute attribute. Please see the inner exception for more details.
However, I have copied both the crossdomain and clientaccesspolicy files into the root of the application in IIS. :( Please help.

You have to deploy your application to the specific ip and port to be able to use it in internet.
I think you can.
To do this you need to edit applicationhost.config file manually (edit bindingInformation '::')
To start iisexpress, you need administrator privileges
1 – Bind your application to your public IP address
Normally when you run an application in IIS Express, it’s only accessible on http://localhost:[someport]. In order to access it from another machine, it needs to be bound to your public IP address as well. Open D:\Users[YourName]\Documents\IISExpress\config\applicationhost.config and find your site. You will find something like this:
<site name="YOUR PROJECT NAME HERE" id="2">
<application path="/">
<virtualDirectory path="/" physicalPath="YOUR PHYSICAL PATH HERE"
<binding protocol="http" bindingInformation="*:58938:localhost" />
</bindings>
</site>
In , add another row:
<binding protocol="http" bindingInformation="*:58938:192.168.1.42" />
(But with your IP, and port number, of course)
2 - Allow incoming connections
If you’re running Windows 7, pretty much all incoming connections are locked down, so you need to specifically allow incoming connections to your application. First, start an administrative command prompt. Second, run these commands, replacing 192.168.1.42:58938 with whatever IP and port you are using:
netsh http add urlacl url=http://192.168.1.42:58938/ user=everyone
This just tells http.sys that it’s ok to talk to this url.
netsh advfirewall firewall add rule name="IISExpressWeb" dir=in protocol=tcp localport=58938 profile=private remoteip=localsubnet action=allow
This adds a rule in the Windows Firewall, allowing incoming connections to port 58938 for computers on your local subnet.
And there you go, you can now press Ctrl-F5 in Visual Studio, and browse you site from another computer!

Related

Hosting multiple WCF services with single certificate

I have three different WCF services deployed on server separately in there own application directory under "Default WebSites" in IIS. One of the service is deployed by me and two other services are deployed by some other client. There is a single server certificate deployed in IIS to which i have bind my service.
But when i try to access my service form https I get this error in popup:
"Address Mismatched.
The security certificate presented by this website was issued for a different website's address.
This problem might indicate an attempt to fool you or intercept any data you send to the server."
Thee web.config file of my service is as following
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<identity impersonate="false" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfApp.Service">
<endpoint address="customer"
binding="basicHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="WCFApp.ICustomerService" />
<endpoint address="order"
binding="basicHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="WcfApp.IOrderService" />
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior >
<serviceMetadata httpsGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="21" maxConcurrentSessions="50" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled="true" />
<validation validateIntegratedModeConfiguration="false" />
</system.webServer>
</configuration>
Interesting thing is that when I hit the following URL:
https://myserverurl.com/applicationfolder/service.svc?wsdl
to get the wsdl, it runs perfectly and returns me the wsdl description but the original call is not working.
Why am I getting the "Mismatched Address"? Is there need to add host base address? if yes how and where exactly to add it in web.config and is there need to add it in other two wcf services deployed? Is port conflicting with certificate? I am new to wcf please help me resolve this issue?
I am using .net 4.0, IIS 7.0, windows server 2008.
Thanks in advance.
The error message says (basically) that the certificate that you are using for your site doesn't match the DNS name that is being used (from the client's browser) to connect to the site.
My guess is that you are implementing virtual hosting; i.e. multiple services with different DNS names that are being served from one IIS instance. This won't work ... unless you either use a different certificate for each service, or you use a wild-card certificate that matches all of the service DNS names.
Apparently, name-based SSL virtual hosting is not supported by IIS prior to 7.0. This article describes how to configure it for IIS 7.0. But note that the names in the respective certificates must match the corresponding virtual host names ...
Note that the requirement that the hostnames and certificates must match is fundamental to SSL security. It is what allows the browser / user to know that it is talking to the expected server (based on the DNS name) and not some imposter site.

Silverlight WCF Service only working on local host

Apologies for the long post but I want to include as much information as possible. So I've been struggling for days now to get my WCF service to work correctly with my silverlight app. I had originally deployed it and everything was running smoothly.
However After i made an update to one of the methods it has not worked since. I use SVN to store my work and even going back to previous versions of the project and redploying it has not helped. Please can someone assist me :(
If I run my silverlight application through VS2012 it works correctly all calls to the service work as required and retrieve the correct information. However if i trigger the same calls once the silverlight app is deployed I receive 1 of the following errors:
An exception occurred during the operation, making the result invalid. Check InnerException for exception details.
at System.ComponentModel.AsyncCompletedEventArgs.RaiseExceptionIfNecessary()
at OrionDashboard.OrionWebService.GetTestDataCompletedEventArgs.get_Result()
at OrionDashboard.MonthlyOverview.OrionWebService_GetTestDataCompleted(Object sender, GetTestDataCompletedEventArgs e)
at OrionDashboard.OrionWebService.OrionWebServiceClient.OnGetTestDataCompleted(Object state)
Or
[Async_ExceptionOccurred] Arguments: Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=4.0.51204.0&File=System.dll&Key=Async_ExceptionOccurred at
With the rest of the error corresponding to the onComplete event error of the other error message.
Again this only happens when its deployed to the IIS on the server, And it only started happening after i made the update an redeployed
I've used both WCF Storm and WCF Test Client that was included with VS2012 to test the deployed service over the network and everything is being returned without any issues for all the contracts.
Here is the ServiceReferences.ClinetConfig:
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinding_OrionWebService">
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://localhost:53493/OrionWebService.svc"
binding="customBinding"
bindingConfiguration="CustomBinding_OrionWebService"
contract="OrionWebService.OrionWebService"
name="CustomBinding_OrionWebService" />
</client>
</system.serviceModel>
I have made no changes to this at all from what was auto generated when i referenced the service project. I thought it may have been this line: "http://localhost:53493/OrionWebService.svc"
because in fiddler i receive the following errors on the crossdomain.xml and the clientaccesspolicy.xml
[Fiddler] The socket connection to localhost failed.
ErrorCode: 10061.
No connection could be made because the target machine actively refused it [::1]:53493
however when i changed the xap to a zip file and modified the ServiceReference.ClientConfig to point to the same service address as would work if you wanted to check your service e.g. "http://ServerName/OrionDashboard/OrionWebService.svc" I still get the same error from silverlight and then get a 404 error from the two files.
Here is the web.config:
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true"
targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="OrionDashboard.Web.OrionWebService.customBinding0">
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="OrionDashboard.Web.OrionWebService">
<endpoint address=""
binding="customBinding"
bindingConfiguration="OrionDashboard.Web.OrionWebService.customBinding0"
contract="OrionDashboard.Web.OrionWebService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
As with the ServiceReference, the web.config too was left alone because I dont really understand what most of it means. But I left it as is when I first deployed the silverlight app and as mentioned it worked fine then.
I don't believe its a DB issue since it runs locally without any issues and the service responds with the correct data from the deployed service as well.
The service seems to be working fine, no issues reported from either the WCF Test Client or WCF Storm app
In VS2012 when publishing the wcf service it doesn't separate the service from the client and it doesn't create the crossdomain.xml or clientaccesspolicy.xml so I manually added those after publishing it. Not sure if that could possibly be the cause?
I'm completely lost and every work around I've found so far has not worked for me. Please can someone at least point me in the right direction?

REST WCF Service hosting(https) in Windows Service on Win2003

I am self hosting a REST WCF service in Windows service. The service exposes a method which returns a boolean and I am able to get the REST webservice to work on WinXp. I also generated a development certificate using makecert and assigned it to the port(1443) that the service listens on. Https also works well on WinXp. But When I use the same in Win2003, and type the URL in IE, it says "The page cannot be displayed". There were no errors in hosting the service, the service listens on the port(the ServiceHost.Open didnt have any errors and its successful). Is there an settings that has to be done in Win2003 for this? Win2003 is the production environment and https has to work on that.
Here is the config file I used,
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="httpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="spectrumServiceBehavior" name="MyApp.TestService">
<host>
<baseAddresses>
<add baseAddress="https://localhost:1443/" />
</baseAddresses>
</host>
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration ="httpBinding"
contract="MyApp.ITestService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="spectrumServiceBehavior">
<!-- 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" />
<serviceMetadata httpsGetEnabled ="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
Any ideas?
I've experienced the same problem. WinXP development environment working with HTTPS, certificate created locally and assigned to a custom port with httpcfg.
Production environment on Windows 2003 with the imported certificate and the same httpcfg configuration giving "interrupted connection" while trying to obtain the WSDL of the service.
Looking at the Windows log I finally found this error:
Event Source: Schannel
A fatal error occurred when attempting to access the SSL server credential private key. The error code returned from the cryptographic module is 0x80090016.
My problem was that I imported the certificate in the user-account store, and then copied in the local store. In this way the private-key is left behind... http://support.microsoft.com/kb/939616 (without even a warning!!!)
despite, opening the certificate in the new location, shows the presence of a private-key!
I expect that on Windows 2003 you must allow application to listen on port (unless it runs as admin) and you must assign SSL certificate to the port - both is performed by httpcfg.exe. Also check that there is no firewall blocking the communication on the port.

Deploying WCF - Need to Set the Host Headers on an SSL Site

Using Visual Studio 2010 / .NET 4.0
I've been at this for hours but I'll try to be specific.
I'm deploying a WCF 4.0 Service to IIS 7. It works fine under http. I can add a service reference from Visual Studio against the WCF service and code against it no problem.
Of course the problem is that the service needs to run under https.
I've managed to manhandle the web.config file so it will run under https (at least I can see the .svc and ?wsdl display in the browser).
But of course IIS is returning the machine name, not the domain name throughout the wsdl.
So when I try to add the service reference I get somehting like this.
The document was understood, but it could not be processed.
- The WSDL document contains links that could not be resolved.
- There was an error downloading 'https://machinename/MyServiceName.svc?xsd=xsd0'.
- The remote name could not be resolved: 'machinename'
I know the problem is that IIS is not returning host headers so WCF is guessing and handing back the machine name.
Of course IIS7 won't allow me to add host headers to a site that is using SSL. I've Googled and seen others set host headers with using appcmd something like this
appcmd set site /site.name: /+bindings.[protocol='https',bindingInformation='*:443:']
Tried it and it tells me that the site has been modified
But instead of modifiying the existing SSL binding I get an additional binding that has a host name, but no certificate attached to it. Any attempt to select a SSL through the IIS UI wipes out the hostname. I'm using a wildcard certificate from GoDaddy
1) Anyone see this problem with appcmd? Have any ideas on how to solve.
2) Can I set the domain name in the webconfig. All my attempts to do so to date have produced various IIS Yellow Screens of Death complaining about one parameter or another. I include a copy for your entertainment and suggestions.
<services>
<service name ="NameThisService" behaviorConfiguration="TheDefaultBehaviour">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="webBinding" contract="IService" >
</endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="webBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</wsHttpBinding>
</bindings >
<behaviors>
<serviceBehaviors>
<behavior name="TheDefaultBehaviour">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false"/>
If the command line doesn't work you CAN do it in the UI. You will need to play around with the Friendly name of the certificate. Link below.
http://blog.armgasys.com/?p=80

WCF WebService / IIS Hosting & Configuration Issue Behind a Firewall

I have a simple WCF Web service. It's hosted on IIS under the default website in our production domain. (local address: 10.10.20.100)
By default this default website was setup for "All Unassigned" IP's on Port 80: however, I noticed that this caused the WCF Service to generate it's WSDL using the servers local DNS name. i.e. all the URIs in the wsdl were
http://myserver.subdomain.domain.com/.../...
This was no good as I need to expose this service to sites who have no knowledge of the production environments internal DNS. And this particular server doesn't have an external DNS Name. Just an external IP Address...
I've had some success with changing the Setting in IIS from "All Unassigned" -> "10.10.20.100"
This causes the Service to generate it's WSDL with the URIs
http://10.10.20.100/.../...
This is fine for other machines within the subdomain and on other subdomains but it's here that I get stuck. The servers External IP Address (1.2.3.4) is mapped through via some NAT/PAT translation so it isn't explicitly setup in the servers IP Settings (i.e. it doesn't show under IP Config)
So if I change the IIS Default Website IP Address from "All Unassigned" -> "1.2.3.4" as I did for the internal address, then the WCF Service just comes back with...
Bad Request (Invalid Hostname)
And if I leave IIS Configured on the Internal IP Address, and try to access the service via the external IP Address I get
No protocol binding matches the given address
'http://1.2.3.4/TestService/Service.svc'. Protocol bindings are
configured at the Site level in IIS or WAS configuration
Is there any way to make IIS/WCF generate it's WSDL URI's with an external IP Address that isn't explicitly configured on the server ?
Someone help me please before I dropkick WCF Services out the window.
It's because you don't have your host headers set. This seems to be an extremely common problem, I run into it all the time. There's no configuration for the uris that it generates, it looks up the right address by examining the host header of the site. Even if it's in a virtual directory, you need to go to the parent, in your case, default directory, and add a host header.
Let me know if you don't know how to do this.
Must it be an IP address and not an FQDN? By swapping to an FQDN and setting that in the host headers for the site, then binding to it via
cscript //nologo %systemdrive%\inetpub\adminscripts\adsutil.vbs set W3SVC/1/ServerBindings ":80:hostname.example.com"
then recycling the app pool will then produce that host name in the generated WSDL. You get benefits with that - you can setup an internal DNS which resolves that FQDN to the internal IP, and an external DNS which resolves to your firewall IP, then the same system will work without any changes.
I might be able to prevent Ninja violence... if I understand your problem ...
You can manually specify the complete address the service should use in the web.config as opposed to having the ServiceHost figure it out for you. You have to set the base address of your service:
<service behaviorConfiguration="Behaviour1" name="Api.Poll">
<endpoint address="soap" binding="basicHttpBinding" bindingConfiguration="soapBinding"
contract="Api.IPoll" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://www.mydomain.com/Api" />
<add baseAddress="http://10.10.20.30/Api" />
</baseAddresses>
</host>
</service>
Using this method, your service should accept the base address specified, plus the service name, with the additional endpoint address if you have one. Also, you would need to use a custom ServiceHostFactory to set the base address programmatically. See below:
public class ServiceHostFactory : System.ServiceModel.Activation.ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
ServiceHost host;
host = new ServiceHost(serviceType, baseAddresses[0]);
return host;
}
Lastly, once you've build the ServiceHostFactory class, you have to hook it up to your service by editing the markup in the .svc file:
<%# ServiceHost Language="C#" Debug="true" Service="Api.Poll" Factory="Api.ServiceHostFactory" CodeBehind="Poll.svc.cs" %>
Here's how you change the header in IIS7. Also put my web.config for some if it helps.
http://www.sslshopper.com/article-ssl-host-headers-in-iis-7.html
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<customErrors mode="Off"></customErrors>
</system.web>
<system.serviceModel>
<client/>
<services>
<service name="WcfService1.Service1"
behaviorConfiguration="MyServiceTypeBehaviors">
<host>
<baseAddresses>
<add baseAddress="https://pws.sjukra.is/"/>
</baseAddresses>
</host>
<endpoint address="https://pws.sjukra.is/Service1.svc"
listenUri="/"
binding="wsHttpBinding"
contract="WcfService1.IService1"
bindingConfiguration="myBasicHttpBindingConfig"/>
<endpoint contract="IMetadataExchange"
binding="mexHttpsBinding"
address="mex"/>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="myBasicHttpBindingConfig">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Windows" />
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug httpsHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
<serviceCredentials type="System.ServiceModel.Description.ServiceCredentials">
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfService1.Service1,WcfService1"/>
<serviceCertificate findValue="pws.sjukra.is" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"></serviceHostingEnvironment>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Even though this is an old thread it actually helped me migrate a project from VS Web Developer Express to MonoDevelop which included a WCF service.
The web application requested the JavaScript interface defined by the WCF service using the following URL: http://127.0.0.1:8080/path-to-service/service.svc/js, which gave me the error: No protocol binding matches the given address
Inspired by this thread I was able to fix the problem because accessing the service with localhost instead of 127.0.0.1 worked! With a request to http://localhost:8080/path-to-service/service.svc/js I got the JavaScript interface.
Actually my application didn't use an absolute URL to include the JavaScript interface, however by default when starting the application from MonoDevelop it would access the application using 127.0.0.1, thus the call to include JavaScript from the service failed.
It's still not perfect since I haven't been able to start the application from MonoDevelop using localhost instead of 127.0.0.1, since the configuration for XSP only allows me to specify an IP address, but at least I know how to get around it.
The problem is that after do a change on port or ip address you shold restart the application pool you using, because it still having the old information until it is recicled.