Как настроить MessageInspector при использовании StandardEndpoints в WCF REST 4.0 - PullRequest
9 голосов
/ 10 июня 2011

Я пытаюсь создать и настроить инспектор сообщений для выполнения некоторой аутентификации HTTP-запроса WCF Rest.Я использую 4.0, поэтому стараюсь держаться подальше от стартового комплекта WCF, хотя мне удалось заставить старый RequestInterceptor работать так, как я хочу.Проблема с использованием RequestInterceptor заключается в том, что я потерял функции automaticFormatSelectionEnabled, предоставляемые WebHttpBehavior, которые я действительно хочу сохранить.

Поэтому мой вопрос заключается в том, как настроить инспектор сообщений таким образом, чтобы я все еще использовал 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>

1 Ответ

19 голосов
/ 22 сентября 2011

Один из способов справиться с этим - создать три объекта.

  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
}

Важно создать буферизованную копию сообщения при его чтении. Сообщения могут быть открыты только один раз, и не создание копии приведет к возникновению проблем. Моя реализация 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
    }

Обратите внимание, что я создаю новый экземпляр моего инспектора (HmacVerificationInspector) и внедряю его программно в среду выполнения.

Наконец, последний шаг - создать раздел конфигурации. Мы можем использовать это, чтобы применить поведение в веб-конфигурации (таким образом, имея возможность включать и выключать его через конфигурацию). Создайте новый класс и унаследуйте от 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();
    }
}

Теперь, чтобы использовать инспектор, добавьте следующее в ваш 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>

Пара вещей, сначала вы регистрируете раздел конфигурации в расширениях поведения. Затем вы используете эту конфигурацию в качестве поведения конечной точки, которая затем автоматически внедрит инспектора, и все запросы к этой конечной точке будут проходить через ваш инспектор. Если вы хотите отключить инспектор, удалите тег или выберите другое поведение конечной точки. Также обратите внимание на использование поведения webHttp (которое позволит вам сохранять automaticFormatSelectionEnabled.

Надеюсь, это поможет

...