views:

5780

answers:

4

I know little about WCF so please bear with me!

In our project we have a java web service that runs over http and https. We want to use http internally and https for the external version of our web app.

So we've created the proxy class in our application and we have setup the binding for http in the web/app.config and all works fine.

What changes would we need to make to the code and the configuration to support https for the same service in our external application? If possible please supply code snippets to explain!

A: 

Please see Configuring HTTP and HTTPS:

Using Windows Communication Foundation (WCF) over HTTP either requires the use of a host, such as Internet Information Services (IIS), or manual configuration of the HTTP settings through the HTTP Server API. This document describes manually configuring WCF when using HTTP and HTTPS.

And also see WCF Bindings Needed For HTTPS:

I just finished writing my first production WCF application, which worked very well until I deployed it to our production environment. All of a sudden none of the WCF calls would work, and I would get a JavaScript "TestService is not defined" error. When I look inside the JS service reference (in debug mode), I got the following error:

Could not find a base address that matches scheme http for the endpoint with binding WebHttpBinding. Registered base address schemes are [https]

So apparently my WCF service registered itself as HTTPS (since it is over SSL), but my binding was only configured for HTTP. The solution is to define a custom binding inside your Web.Config file and set the security mode to "Transport". Then you just need to use the bindingConfiguration property inside your endpoint definition to point to your custom binding. The entire HTTPS-enabled system.serviceModel section is below:

Andrew Hare
A: 

I understand that you are using WCF to build the client, that connects to a remote web service, over HTTPS.

To do this, just modify the client-side config file for the WCF-powered app, replacing http://server.address with https://server.address, in configuration/system.serviceModel/client/endpoint/@address . like so:

<configuration>
  <system.serviceModel>
    ...
    <client>
        <!-- change only the address string -->
        <endpoint address="https://server.name/Whatever"
            everything.else.stays.the.same />

    </client>
  </system.serviceModel>
</configuration>

(The path to the config file varies according to the regular .NET rules: whether it is an ASPNET app, or a service, or etc.)

OR you can set the address explicitly in code:

    // instantiate new proxy to web service
    var svc= new ServiceClient();
    var e = svc.Endpoint;
    e.Address = new System.ServiceModel.EndpointAddress("https://server.address/JavaServiceUri");

I strongly advise you to make the address configurable, and not hard-code it. That does not mean it must be stored in app.config, but it should be changeable. The proxy, too.

Cheeso
A: 

I am assuming that you are using basichttpbinding. Then you need to do two things:

  • change the address to https :)
  • set the security mode to transport

It is covered in this link:

http://stackoverflow.com/questions/951204/calling-a-web-service-using-wcf-over-http-and-https

Shiraz Bhaiji
+2  A: 

None of the above helped me. Digging around MSDN did.

In my case, I was using a custom binding:

<customBinding>
    <binding name="jsonpBinding">
        <jsonpMessageEncoding/>
        <httpTransport manualAddressing="true"/>
    </binding>
</customBinding>

That was referenced in the service

<services>
    <service name="{YourInfoHere}">
        <endpoint address="" binding="customBinding" bindingConfiguration="jsonpBinding" behaviorConfiguration="{YourInfoHere}" contract="{YourInfoHere}"/>
    </service>
</services>

Adding a second binding that used httpsTransport and then a second service that used that binding did the trick. Final output:

    <services>
        <service name="{YourInfoHere}">
            <endpoint address="" binding="customBinding" bindingConfiguration="jsonpBinding" behaviorConfiguration="{YourInfoHere}" contract="{YourInfoHere}"/>
            <endpoint address="" binding="customBinding" bindingConfiguration="jsonpBindingHttps" behaviorConfiguration="{YourInfoHere}" contract="{YourInfoHere}"/>
        </service>
    </services>
    <bindings>
        <customBinding>
            <binding name="jsonpBinding">
                <jsonpMessageEncoding/>
                <httpTransport manualAddressing="true"/>
            </binding>
            <binding name="jsonpBindingHttps">
                <jsonpMessageEncoding/>
                <httpsTransport manualAddressing="true" />
            </binding>
        </customBinding>
    </bindings>

May not be ideal, but it works. These were the only changes I made to make SSL work. Since it is all in the binding & transport, the code remains the same.

Relevant MSDN links:

  1. Custom Binding: http://msdn.microsoft.com/en-us/library/ms731377.aspx
  2. HttpTransport: http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.httptransportbindingelement.aspx
  3. HttpsTransport: http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.httpstransportbindingelement.aspx
jeffreypriebe
@jeffreypriebe - +1 -Exactly what I was looking for :)
Wallace Breza