Question

I am planning to publish my Web Service so it can be used on outside network. The issue comes about is that the Web Admins do not want to make this web service external but want me to wrap a proxy around it and make the proxy external. I am not liking the proxy part due to than having to maintain versioning on both the Service and the Proxy. I was wondering if there is a simple way to do this, if you accessing the webservice using outside network (URL) to use SSL and request authentication but if you are using it in internal network (URL) to not request authentication or SSL. I tried having two endpoint configuration in webconfig one secure and one not secure but the problem is when you consume the webservice both bindings show and the client can choose one or the either. If anyone has done this differently or reccomends a different way let me know, usually I do one approach either all secure or all non secure but not different depending on network. Thanks much :)

Was it helpful?

Solution

You'll be please to know that WCF has built-in support for your 'Proxy'. It is called the Routing Service and is available in WCF 4.0 and later.

You can configure it to route the internet calls for a certain service contract to the WCF service running in your intranet. It can even translate bindings so that your internal service using TCP bindings can be called by external customers using a HTTP binding that can pass through your firewall.

It only needs to know what contracts to route to where. So no need to update it when your contracts change...

See here for more info.

EDITED: The following example system.serviceModel node allows a client to add a service reference to the routed service. The trick is to let the routing service impose itself as the service(s) it is routing to. See the serviceActivations node for that. Note that this removes the need to have a .svc file.

Next we define two endpoint filters to redirect the requests for the service to the routed service and the requests for the mex endpoint (which exposes the metadata) to the mex endpoint of the routed service. See the filters node for that.

Last, we explicitly disable exposing the metadata of the routing service itself via http to force clients to use mex (which we are routing) for the discovery. See the serviceBehaviors node for that.

EDITED AGAIN: added solution for mex size limit

<system.serviceModel>
  <serviceHostingEnvironment>
    <serviceActivations>
      <!--Lets the routing service impose himself as Service.svc  (No .SVC file is needed!!!) -->
      <add service="System.ServiceModel.Routing.RoutingService" relativeAddress="Service.svc" />
    </serviceActivations>
  </serviceHostingEnvironment>
  <bindings>
    <wsHttpBinding>
      <!-- a mexHttpBinding is in fact a wsHttpBinding with security turned off -->
      <binding name="mexBinding" maxReceivedMessageSize="5000000">
        <security mode="None"/>
      </binding>
    </wsHttpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
      <behavior >
        <!-- Use the filter table with the name 'Filters' defined below -->
        <routing routeOnHeadersOnly="false" filterTableName="Filters"/>
        <serviceDebug includeExceptionDetailInFaults="true"/>
        <!-- Disable exposing metadata for this routing service to force discovery using mex -->
        <serviceMetadata httpGetEnabled="false"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <routing>
    <filters>
      <!-- Declare a routing filter that filters on endpoint Service.svc -->
      <filter name="WcfServiceFilter" filterType="EndpointAddress" filterData="http://localhost/ServiceRouter/Service.svc" />
      <!-- Declare a routing filter that filters on mex endpoint of Service.svc -->
      <filter name="WcfServiceFilter.mex" filterType="EndpointAddress" filterData="http://localhost/ServiceRouter/Service.svc/mex"/>
    </filters>
    <filterTables>
      <!-- Declare the routing table to use -->
      <filterTable name="Filters">
        <!-- requests that match the WcfServiceFilter (declared above) should be routed to the client endpoint WcfService -->
        <add filterName="WcfServiceFilter" endpointName="WcfService"/>
        <!-- requests that match the WcfServiceFilter.mex (declared above) should be routed to the client endpoint WcfService.mex -->
        <add filterName="WcfServiceFilter.mex" endpointName="WcfService.mex"/>
      </filterTable>
    </filterTables>
  </routing>
  <services>
    <!-- Declare our service instance and the endpoints it listens on -->
    <service name="System.ServiceModel.Routing.RoutingService">
      <!-- Declare the endpoints we listen on -->
      <endpoint name="WcfService" contract="System.ServiceModel.Routing.IRequestReplyRouter" binding="wsHttpBinding" />
      <endpoint name="WcfServiceFilter.mex" address="mex" contract="System.ServiceModel.Routing.IRequestReplyRouter" binding="mexHttpBinding" />
    </service>
  </services>
  <client>
    <!-- Define the client endpoint(s) to route messages to -->
    <endpoint name="WcfService" address="http://localhost/WcfService/Service.svc" binding="wsHttpBinding" contract="*" />
    <endpoint name="WcfService.mex" address="http://localhost/WcfService/Service.svc/mex" binding="wsHttpBinding" bindingConfiguration="mexBinding" contract="*" />
  </client>
</system.serviceModel>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top