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

前端 未结 1 677
抹茶落季
抹茶落季 2020-12-29 13:00

I\'m trying create and configure a Message Inspector to perform some authentication of a WCF Rest HTTP request. I\'m using 4.0 so trying to steer clear of the WCF Starter Ki

相关标签:
1条回答
  • 2020-12-29 13:55

    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

    0 讨论(0)
提交回复
热议问题