Disable proxy output for /jsdebug or /js endpoint of WCF service consumed using Javascript or Ajax

This post has been republished via RSS; it originally appeared at: IIS Support Blog articles.

Recently I worked on a scenario where we had to disable the proxy output for /jsdebug or /js endpoint for security concerns: We were able to achieve the same using following steps:

 

When we consume a Wcf service or Webservice  using Java script client or ASP.NET Ajax page  via a servicehost factory defined as WebScriptServiceHostFactory, We expose the client side javascript proxy information via the endpoint /WcfService.svc/jsdebug or /WcfService.svc/js which we use in the client end to invoke the Wcf service.

 

Here we have highlighted the steps for creating Wcf Service and exposing the client side javascript proxy information using Factory type as WebScriptServiceHostFactory so the same can be consumed via javascript or an ASP.NET Ajax page:

 

Also, How to disable the proxy output exposed via /jsdebug or /js due to security constrains or hide the proxy information when required.

 

 

Step 1: Creating the wcf service and exposing the javascript client end proxy information over the /jsdebug endpoint.

 

  1. Open Visual Studio and create the WCF Service Library named WCFService1.
  2. Now we will create the Operation Contract in the interface as below:
namespace WcfService1 { [ServiceContract] public interface IService1 { [OperationContract] string GetData(int value); // TODO: Add your service operations here } }

 

  1. Create the Service Class with the following code:
namespace WcfService1 { public class Service1 : IService1 { public string GetData(int value) { return string.Format("You entered: {0}", value); } } }
  1. In your Web.config file add the below section:
<system.serviceModel> <services> <service name="WcfService1.Service1" behaviorConfiguration="beh"> <endpoint address="" binding="basicHttpBinding" name="soap" contract="WcfService1.IService1"/> </service> </services> <serviceBehaviors> <behavior name="beh"> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> </behavior> </serviceBehaviors> </system.serviceModel>

The rest is configured automatically.

 

  1. Now we will create another ASP.NET project and add it to the solution which will be the client application.

 

Now add a text file in the application and save it as "Ajaxservice.svc". Add the WCFService1 project reference in the asp.net Web Application. Copy the following code to the file "Ajaxservice.svc" :

<%@ServiceHost language="C#" debug="false" Service="WcfService1.Service1" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"%>

Build the Project. Right click on the Ajaxservice.svc file and browse it in the browser.

Meghali_0-1618609090938.png

 

 

 

  1. Now we will modify the url to add jsdebug http://localhost:10253/Ajaxserv.svc/jsdebug to get the javascript proxy information and we see the below output:

Meghali_1-1618609090953.png

 

Step 2: To disable the output for the /jsdebug or /js endpoint so that the proxy information is not exposed and other security reasons please follow the below approach in your client application consuming the service:

 

  • We need to use the approach of filtering it out using message inspector.
  • We need to create a behavior which iterates through ServiceHostBase.ChannelDispatchers to find it's index and then remove it. We need to do it in IServiceBehavior.ApplyDispatchBehavior.

We need to use endpointDispatcher.ChannelDispatcher.Host to get the instance of ServiceHostBase, then access ChannelDispatchers to get the collection of ChannelDispatcher instances. We can use ChannelDispatcher.Listener.Uri to get the listen address to see if the instance is the right one.

 

  • We add a class  file to the ASP.net Web Application and add the below code as a part of the message inspector to block the output for .jsdebug and .js

 

public class DisableJSDebugServiceBehavior : IServiceBehavior, IEndpointBehavior { #region IServiceBehavior public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (var endpoint in serviceHostBase.Description.Endpoints) { endpoint.EndpointBehaviors.Add(this); } } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } #endregion // IServiceBehavior #region IEndpointBehavior public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { ServiceHostBase host = endpointDispatcher.ChannelDispatcher.Host; for(int i=0; i< host.ChannelDispatchers.Count; i++) { if(host.ChannelDispatchers[i].Listener.Uri.ToString().IndexOf("jsdebug", StringComparison.OrdinalIgnoreCase) >= 0) { host.ChannelDispatchers.RemoveAt(i); } } for (int i = 0; i < host.ChannelDispatchers.Count; i++) { if (host.ChannelDispatchers[i].Listener.Uri.ToString().IndexOf("js", StringComparison.OrdinalIgnoreCase) >= 0) { host.ChannelDispatchers.RemoveAt(i); } } } public void Validate(ServiceEndpoint endpoint) { } #endregion // IEndpointBehavior } public class DisableJSDebugServiceBehaviorElement : BehaviorExtensionElement { public override Type BehaviorType => typeof(DisableJSDebugServiceBehavior); protected override object CreateBehavior() { return new DisableJSDebugServiceBehavior(); } }

 

 

Meghali_2-1618609090957.png

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.