在WCF REST 4.0中使用StandardEndpoints时如何配置MessageInspector

Jon*_*ree 9 wcf message behavior inspector

我正在尝试创建并配置Message Inspector以执行WCF Rest HTTP请求的某些身份验证.我正在使用4.0,所以我试图避开WCF入门套件,尽管我已经设法让我的旧RequestInterceptor以我想要的方式工作.使用RequestInterceptor的问题是我丢失了WebHttpBehavior提供的automaticFormatSelectionEnabled功能,我真的想保留它.

所以我的问题是如何配置Message Inspector,我仍然使用WebHttpBehavior并保留它的功能.

我的web.config看起来像这样

    <standardEndpoints>
  <webHttpEndpoint>
    <!-- the "" standard endpoint is used by WebServiceHost for auto creating a web endpoint. -->
    <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
    <!-- Disable the help page for the directory end point-->
    <standardEndpoint name="DirectoryEndpoint"/>
  </webHttpEndpoint>
</standardEndpoints>
Run Code Online (Sandbox Code Playgroud)

Jay*_*k84 19

您可以处理此问题的一种方法是创建三个对象.

  1. 消息检查器,负责分析请求/响应
  2. 服务行为自动将检查器注入管道
  3. 配置部分允许在web.config中使用该行为

首先通过实现IDispatchMessageInspector并将验证代码放在AfterReceiveRequest方法中来创建消息检查器:

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
}
Run Code Online (Sandbox Code Playgroud)

在阅读时创建消息的缓冲副本非常重要.消息只能打开一次而不创建副本会导致管道出现问题.如果失败,我的ValidateHmac实现会抛出异常.这可以防止调用实际服务.

其次,为检查员创建一种行为.我们将使用该行为将检查器注入WCF运行时.要创建行为,请从IEndpointBehavior派生一个类,使其看起来像这样

 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
    }
Run Code Online (Sandbox Code Playgroud)

注意我创建了一个新的inspector(HmacVerificationInspector)实例,并以编程方式将其注入运行时.

最后,最后一步是创建配置部分.我们可以使用它来在Web配置中应用行为(因此可以通过配置打开和关闭它).创建一个新类并从BehaviorExtensionElement和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();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,要使用检查器,请将以下内容添加到web.config中(您可以将扩展名设置为您想要的任何内容)

<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>
Run Code Online (Sandbox Code Playgroud)

有几件事,首先在行为扩展中注册配置部分.接下来,您将该配置用作端点行为,然后将自动注入检查器,并且所有对该端点的请求将通过检查器运行.如果要关闭检查器,请删除标记或选择其他端点行为.注意也使用了webHttp行为(这将允许你保持automaticFormatSelectionEnabled.

希望这可以帮助