WCF with HTTPS on Azure - wcf

I have set up a web role that hosts two endpoints (one HTTP and the other HTTPS). Both endpoints are pointing to the same service Main.svc which is configured to be RESTful. This is my configuration (showing only the HTTPS one as it's the one giving me problem):
<services>
<service behaviorConfiguration="AthenaBehaviorConfigHttps" name="Athena.LEC.Service.Main">
<endpoint address="" behaviorConfiguration="AthenaBehaviorEndpointConfig"
binding="webHttpBinding" contract="Athena.LEC.Service.IMain" />
<endpoint binding="basicHttpBinding" bindingConfiguration="SecureBasic" name="basicHttpSecure" contract="Athena.LEC.Service.IMain" />
</service>
</services>
Behavior config:
<behavior name="AthenaBehaviorConfigHttps">
<serviceMetadata httpsGetEnabled="true" httpsGetUrl="" httpGetEnabled="true" httpGetUrl="" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
Basic http binding:
<basicHttpBinding>
<binding name="SecureBasic">
<security mode="Transport" />
</binding>
</basicHttpBinding>
On the Azure web role configuration:
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="HttpEndpoint" />
<Binding name="Endpoint2" endpointName="HttpsEndpoint" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="HttpEndpoint" protocol="http" port="7902" />
<InputEndpoint name="HttpsEndpoint" protocol="https" port="7955" />
</Endpoints>
On HTTP I have verified that the restful call was successful. However, on port 7955 (configured as Https), when I use my browser to make a call it just resulted in an empty page (normally the JSON result will be returned). Is this normal? Or am I configuring something wrongly? Thanks!

Change your binding to use basicHttp*s*Binding instead. I show how to secure WCF endpoints for http and tcp in this post. So, you can use it as a reference to check against your solution.

Related

WCF service self hosting with https

Currenlty there is a Wcf service hosted as windows service in one of our client side machine, actually currently this is working with normal http call. As we need to use https instead of http, for that we modified app.config but after starting the service the https url not working.Then we tried URL reservation by using netsh http add urlacl url=https://+:18732/Peripheral/ user=Everyone.Then we restared the service again it's not able to access the https url.
we are getting the error in the URl browser •Make sure that TLS and SSL protocols are enabled.
Is this related to any certificate issue? if so how we can able to solve this issue?
The web.config is provied below:-
<system.serviceModel>
<standardEndpoints />
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<bindings>
<basicHttpBinding>
<binding name ="soapBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="Bind1" crossDomainScriptAccessEnabled="true">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="Peripheral.Server.Impl.PeripheralServiceImpl" behaviorConfiguration="SvcBhvr">
<host>
<baseAddresses>
<add baseAddress="https://localhost:18732/Peripheral/" />
</baseAddresses>
</host>
<endpoint address="https://localhost:18732/Peripheral/" binding="webHttpBinding" behaviorConfiguration="EndPBhvr" bindingConfiguration="Bind1"
contract="Peripheral.Server.Contract.IPeripheralService">
<!--<identity>
<dns value="localhost" />
</identity>-->
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="EndPBhvr">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="SvcBhvr">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Anyone knows how to fix this and what we needed to do so that we could able to access the url as https from windows services?
You may need also to bind ssl certificate to the specific port number using netsh or HttpConfig tool depending from OS version. Detailed instructions can be found here
In your case it could be:
netsh http add sslcert ipport=0.0.0.0:18732 certhash=<certhash> appid={<guid>} clientcertnegotiation=enable
where
certhash = your certificate Thumbprint(X509Certificate2.Thumbprint)
appid = could be just Guid.NewId()

Silverlight 404 on service with SSL enabled

I've tried a lot of tips on this one but I cannot get it working. On the client I have:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="[binding_name]">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="/[service_name].svc"
binding="basicHttpBinding"
bindingConfiguration="[binding_name]"
contract="[contract_name]"
name="[endpoint_name]" />
</client>
</system.serviceModel>
</configuration>
And on the server:
...<service name="[service_name]">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="[binding_name]"
contract="[contract_name]"
name="[endpoint_name]"/>
<endpoint contract="IMetadataExchange"
binding="mexHttpsBinding"
address="mex" />
</service><behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors><bindings>
<basicHttpBinding>
<binding name="[binding_name]">
<security mode="Transport">
<transport clientCredentialType ="None"/>
</security>
</binding>
</basicHttpBinding>...
One potential clue is that when I navigate to https://[server_name]/[service_name].svc?wsdl, I see the location is correct on
<wsdl:import namespace="http://[namespace]" location="https://[server_name]/[service_name].svc?wsdl=wsdl0"/>
but incorrect on
<wsdl:port name="[binding_name]" binding="tns:[binding_name]">
<soap:address location="http://[machine_name]/[service_name].svc"/>
</wsdl:port>
Notice location="http://[machine_name]/[service_name].svc" Is that expected? If not, what could be the problem?
I've also made sure that [service_name] in the server configuration is the FQN of the service implementation. Everything worked as expected before I enabled SSL on the server and changed the security mode to transport, etc.
The problem in my case was the fact that though the service_name in <service name="[service_name]"> was the correct FQN of the service implementation, it did not match the Service attribute in the *.svc file. In that case it seems that WCF creates a default name for the endpoint, which is something like BasicHttp_service_name. That worked until SSL was enabled and was looking for the endpoint with a URL starting with https.
As for the machine_name issue, it was because I didn't set the host name for https in the IIS site bindings.

WCF HTTPS and multiple sites in IIS

I am trying to configure IIS to host one set of binaries in two IIS websites. So we want to be able to access the urls:
http://external.example.com/ADataService
https://external.example.com/ADataService
http://internal.example.com/ADataService
internal.example.com and external.example.com are set up as different IIS sites to allow us to assign them different application pools. However when I added HTTPS support to our web.config, the internal HTTP support stopped working; http://internal.example.com/ADataService now returns the error:
Could not find a base address that matches scheme https for the endpoint with binding CustomBinding. Registered base address schemes are [http].
Here are the details of our web.config
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<customBinding>
<binding name="jsonCustomMapper">
<webMessageEncoding webContentTypeMapperType="Service.JSONCustomMapper, Service" />
<httpTransport manualAddressing="true" />
</binding>
<binding name="httpsjsonCustomMapper">
<webMessageEncoding webContentTypeMapperType="Service.JSONCustomMapper, Service" />
<httpsTransport manualAddressing="true" />
</binding>
</customBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="Service.Service" behaviorConfiguration="defaultBehavior">
<endpoint address="json" binding="customBinding" bindingConfiguration="jsonCustomMapper" behaviorConfiguration="jsonBehavior" contract="Service.IJSONService" />
<endpoint address="json" binding="customBinding" bindingConfiguration="httpsjsonCustomMapper" behaviorConfiguration="jsonBehavior" contract="Service.IJSONService" />
</service>
</services>
</system.serviceModel>
From what I understand multipleSiteBindingsEnabled="true" and HTTPS do not mix, but I don't understand what resources they would be sharing? If we have internal.example.com and external.example.com hosted in different app pools, I thought they would have process isolation?
seems that adding an HTTPS certificate to the site for "internal.example.com" fixed the issue. Note: without this certificate we were not able to access internal.example.com over either HTTP or HTTPS, with certificate both mechanisms work correctly.

wcf with basic authentication through reverse proxy

I have a Web Service which uses basic authentication with ssl through a reverse proxy. It has already cost me quite some time to figure out how to get this working and I still fail to get it fully working.
if you type in the url in the browser https://domain.com/service.svc, it asks for credentials and if correct, you get the overview page of the service.
So that seems to be okay.
But when I try to add the Service to Visual Studio 2010, I get the following error:
Metadata contains a reference that cannot be resolved:
The document format is not recognized (the content type is 'text/html; charset=utf-8').
Metadata contains a reference that cannot be resolved: 'https://domain.com/service.svc'.
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Basic realm=NTLM'.
The remote server returned an error: (401) Unauthorized.
If the service is defined in the current solution, try building the solution and adding the service reference again.
Here is my web.config
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyBinding">
<!--<httpsTransport authenticationScheme="Basic"/>-->
<security mode="TransportCredentialOnly">
<transport clientCredentialType="None" proxyCredentialType="Basic" realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WcfService1.PortalService" behaviorConfiguration="NorthwindBehavior">
<host>
<baseAddresses>
<add baseAddress="https://domain.com/" />
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="MyBinding" contract="WcfService1.IPortalService">
<!--<identity>
<servicePrincipalName value=""/>
</identity>-->
</endpoint>
<!--<endpoint address="mex" binding="basicHttpBinding" bindingConfiguration="MyBinding" name="mex" contract="WcfService1.IPortalService"></endpoint>-->
</service>
</services>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="https://domain.com/"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<!--<extensions>
<bindingElementExtensions>
<add name="httpsViaProxyTransport" type="WcfService1.HttpsViaProxyTransportElement, WcfService1"/>
</bindingElementExtensions>
</extensions>
<bindings>
<customBinding>
<binding name="UserNamePasswordSecured">
<textMessageEncoding />
<security authenticationMode="UserNameOverTransport" />
<httpsViaProxyTransport />
</binding>
</customBinding>
</bindings>-->
<behaviors>
<serviceBehaviors>
<behavior name="NorthwindBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceAuthorization principalPermissionMode="UseAspNetRoles"/>
<serviceCredentials> <userNameAuthentication userNamePasswordValidationMode="MembershipProvider"/></serviceCredentials>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="SampleEndpointBehavior">
<!--<wsdlExtensions location="http://domain.com/PortalService.svc" singleFile="true"/> -->
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
I tried numerous things like following this post: http://blog.hackedbrain.com/2006/09/26/how-to-ssl-passthrough-with-wcf-or-transportwithmessagecredential-over-plain-http/ but not very succesful.
I also tried to add site bindings to http because the wsdl is generating the server name instead of the domain name, so maybe there is something wrong at that end as well...
So hopefully someone can provide me with some pointers!
Note that the web.config file has some 'junk' in it because of trying with million different settings...

Why can't I get my Azure, WCF, REST, SSL project working? What am I doing wrong?

I'm trying to get SSL, WCF and REST under Azure, but the page won't even load.
Here are the steps I followed:
1) I mapped the www.mydomain.com CNAME to my azuresite.cloudapp.net
2) I procured an SSL certificate for www.mydomain.com and properly installed it at my azuresite.cloudapp.net hosted service project
3) I deployed my WCF REST service to Azure and started it. Below is my web.config configuration.
The http (non-https) binding version worked correctly. My service URL, http: //www.mydomain .com/service.svc/sessions worked just fine.
When I deployed the project with the web.config below, enabling SSL, https: //www.mydomain .com/service.svc/sessions does not even pull up at all.
What am I doing wrong?
<system.serviceModel>
<services>
<service name="Service">
<!-- non-https worked just fine -->
<!--
<endpoint address="" binding="webHttpBinding" contract="IService" behaviorConfiguration="RestFriendly">
</endpoint>
-->
<!-- This does not work, what am I doing wrong? -->
<endpoint address="" binding="webHttpBinding" bindingConfiguration="TransportSecurity" contract="IService" behaviorConfiguration="RestFriendly">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="RestFriendly">
<webHttp></webHttp>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="TransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
Did you add the https endpoint to your web role in the ServiceDefinition.csdef file?
It should look something like this:
<WebRole name="WebRole">
<InputEndpoints>
<InputEndpoint name="HttpIn" protocol="http" port="80" />
<InputEndpoint name="HttpsIn" protocol="https" port="443" />
</InputEndpoints>
</WebRole>
See http://blogs.msdn.com/jnak/archive/2009/05/12/https-endpoint-on-windows-azure.aspx for more info.
You may be missing a service behaviour. Try adding this:
<serviceBehaviors>
<behavior name="RestService">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
Then when you define your service:
<service behaviorConfiguration="RestService" name="WebService.Rest">
Edit
Another thing that could be the problem, is that the request is not reaching your webrole. Have you set up an inputEndpoint for SSL? see Link