How do you configure a MessageInspector when using StandardEndpoints in WCF REST 4.0

偶尔善良 提交于 2019-11-30 05:12:58

One way you can handle this is to create three objects.

  1. The message inspector, responsible for analyzing the request/response
  2. The service behavior, automatically injects the inspector into the pipeline
  3. The configuration section, allows the behavior to be used in the web.config

First create the message inspector by implementing IDispatchMessageInspector and putting your validation code in the AfterReceiveRequest method:

public class HmacVerificationInspector : IDispatchMessageInspector
{

    #region IDispatchMessageInspector Members

    public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, 
        System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
    {
            MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
            request = buffer.CreateMessage();
            Message dupeRequest = buffer.CreateMessage();

            ValidateHmac(dupeRequest);

            buffer.Close();

        return null;
    }

    public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, 
        object correlationState)
    {


    }

    #endregion
}

It's important to create a buffered copy of the message when reading it. Messages can only be opened once and not creating a copy will lead to problems down the pipe. My implementation of ValidateHmac throws an exception if it fails. This prevents the actual service from being called.

Second, create a behavior for your inspector. We'll use the behavior to inject the inspector into the WCF runtime. To create the behavior, derive a class from IEndpointBehavior so it looks like this

 public class HmacVerificationBehavior : IEndpointBehavior
    {
        #region IEndpointBehavior Members

        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {

        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {

        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
        {
            HmacVerificationInspector inspector = new HmacVerificationInspector();

            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
        }

        public void Validate(ServiceEndpoint endpoint)
        {

        }

        #endregion
    }

Notice I create a new instance of my inspector (HmacVerificationInspector) and inject it programmatically into the runtime.

Finally, the last step is to create a configuration section. We can use this to apply the behavior in the web config (thus being able to turn it on and off via configuration). Create a new class and inherit from BehaviorExtensionElement and IServiceBehavior:

public class HmacVerificationConfigurationSection : BehaviorExtensionElement, IServiceBehavior
{
    #region IServiceBehavior Members

    public void AddBindingParameters(ServiceDescription serviceDescription, 
        System.ServiceModel.ServiceHostBase serviceHostBase, 
        System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, 
        System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
    {

    }

    public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
    {

    }

    #endregion

    public override Type BehaviorType
    {
        get { return typeof(HmacVerificationBehavior); }
    }

    protected override object CreateBehavior()
    {
        return new HmacVerificationBehavior();
    }
}

Now, to use the inspector, add the following to your web.config (you can set the name for your extension to whatever you want)

<system.serviceModel>
        <extensions>
            <behaviorExtensions>
                <add name="hmacVerification" type="NamespaceHere.HmacVerificationConfigurationSection, AssembleyHere, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
            </behaviorExtensions>
        </extensions>
        <services>
            <service name="MySecureService">
                <endpoint address="" binding="webHttpBinding" contract="IMySecureService" behaviorConfiguration="web" />
            </service>
        </services>
        <behaviors>
            <endpointBehaviors>
                <behavior name="web">
                    <webHttp automaticFormatSelectionEnabled="true" />          
                    <hmacVerification />
                </behavior>
            </endpointBehaviors>
            <serviceBehaviors>
                <behavior name="">
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
    </system.serviceModel>

Couple of things, first you register the configuration section in the behavior extensions. Next, you use that configuration as an endpoint behavior which will then automatically inject the inspector and all requests to that endpoint will run through your inspector. If you want to turn off the inspector, remove the tag or select a different endpoint behavior. Note the use of the webHttp behavior also (which will allow you to keep automaticFormatSelectionEnabled.

Hope this helps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!