4
votes

I’ve searched through several posts (here and here, for example) related to this area, but none seem to address this fairly straight forward scenario question: What Binding configurations should be used to configure an SSL enabled (e.g. https) WCF Web Service on an Azure Web Role: in the Web Role’s ServiceDefinition.csdef, the Web Service’s web.config and the client’s app.config?

I have configured the SSL cert for the service in the Azure Portal and in the Web Role’s ServiceConfiguration.csfg for https:// MyApp.cloudapp.net and this appears to be working fine.

When I browse to the service https:// myapp.cloudapp.net/WCFService.svc?wsdl , the metadata displays correctly. I can add a Service Reference to the service from a client, but when I call it, I get the exception: “There was no endpoint listening at https:// myapp.cloudapp.net/WCFService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.” Inner Exception: “The remote server returned an error: (404) Not Found”

The respective configuration files look like this: ServiceDefinition.csdef :

<WebRole name="WCFServiceWebRole" vmsize="Small">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="HttpIn" endpointName="HttpIn" />
          <Binding name="HttpsIn" endpointName="HttpsIn" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="8080" />
      <InputEndpoint name="HttpsIn" protocol="https" port="443" certificate="MySSLCert" />
    </Endpoints>
    <Certificates>
      <Certificate name="MySSLCert" storeLocation="LocalMachine" storeName="My" />
    </Certificates>
  </WebRole>

Web Service’s web.config :

<system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>              
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding" />
          <security mode="Transport">
            <transport clientCredentialType="None" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>

The Client’s App.Config looks like this:

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IMyWebService" >
                 <security mode="Transport">
                    <transport clientCredentialType="None" />
                 </security>
             </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://myapp.cloudapp.net/MyWebService.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyWebService"
                contract="MyWebServiceServiceReference.IMyWebService"
                name="BasicHttpBinding_IMyWebService" />
        </client>
    </system.serviceModel>

When I use SvcUtil to generate the binding configuration for the client, it generates:

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IMyWebService" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://myapp.cloudapp.net/MyWebService.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyWebService"
                contract="MyWebServiceServiceReference.IMyWebService" name="BasicHttpBinding_IMyWebService" />
        </client>
    </system.serviceModel>

Which then gives the exception when I call the web service: "The provided URI scheme 'https' is invalid; expected 'http'." So that doesn't seem to be the correct configuration either.

I’m sure this is just a matter of getting the right configuration in the three files above, but I can’t seem to find the correct combination anywhere, and so I would really appreciate if someone could call out what they should be. Conor.

2

2 Answers

4
votes

An Azure dev helped me figure out the answer to this, the problem was the omission of the Service node from the Web Service's web.config file. Here is the full set of configuration files required for this scenario in case it helps anyone else trying to achieve the same result (An SSL/HTTPS WCF Web Service implemented on an Azure Web Role:

ServiceDefinition.csdef :

<WebRole name="WCFServiceWebRole" vmsize="Small">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="HttpIn" endpointName="HttpIn" />
          <Binding name="HttpsIn" endpointName="HttpsIn" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="8080" />
      <InputEndpoint name="HttpsIn" protocol="https" port="443" certificate="MySSLCert" />
    </Endpoints>
    <Certificates>
      <Certificate name="MySSLCert" storeLocation="LocalMachine" storeName="My" />
    </Certificates>
  </WebRole>

Web Service’s web.config :

<system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>              
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding" />
          <security mode="Transport">
            <transport clientCredentialType="None" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="" name="MyWebServiceNameSpace.MyWebService">
      <endpoint bindingConfiguration="BasicHttpBinding" address="" binding="basicHttpBinding"
    contract="MyWebServiceNameSpace.IMyWebService" />
      <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
     </service>
   </services>
  </system.serviceModel>

The Client’s App.Config looks like this:

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IMyWebService" >
                 <security mode="Transport">
                    <transport clientCredentialType="None" />
                 </security>
             </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://myapp.cloudapp.net/MyWebService.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyWebService"
                contract="MyWebServiceServiceReference.IMyWebService"
                name="BasicHttpBinding_IMyWebService" />
        </client>
    </system.serviceModel>
0
votes

Thanks, works for me too! I made some changes removing the certificates section in the service definition.

<WebRole name="WCFServiceBizagiCloud" vmsize="Standard_D1_v2">
    <Sites>
      <Site name="Web">
        <Bindings>
          <!--<Binding name="Endpoint1" endpointName="Endpoint1" />-->
          <Binding name="HttpIn" endpointName="HttpIn" />
          <Binding name="HttpsIn" endpointName="HttpsIn" />
        </Bindings>
      </Site>
    </Sites>
    <ConfigurationSettings>
      <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" />
    </ConfigurationSettings>
    <Endpoints>
      <!--<InputEndpoint name="Endpoint1" protocol="http" port="80" />-->
      <InputEndpoint name="HttpIn" protocol="http" port="8080" />
      <InputEndpoint name="HttpsIn" protocol="https" port="443"  />
    </Endpoints>
    <!--<Certificates>
      <Certificate name="MySSLCert" storeLocation="LocalMachine" storeName="My" />
    </Certificates>-->
  </WebRole>