locked
WCF Message Interceptor SOAP RRS feed

  • Question

  • User-1753096817 posted

    This question appears to have been asked multiple times, but I just can't get it to work, so forgive me for appearing to be a complete newbie.

    Firstly I have now tried this on both Windows 7 and Windows 8 using VS 2012 on both and have exactly the same problem.

    I am trying to write a WCF service that receives and processes a SOAP header message and after a lot of searching have found that I should be using a Message Interceptor to read and process the SOAP header.

    So I have created a new web site on my local machine and called it DemoMessageInspector. Within this solution I have added the following classes:

    HmacVerificationBehavior

    Imports System.ServiceModel.Description

        Public Class HmacVerificationBehavior        

                      Implements IEndpointBehavior      

                      #Region "IEndpointBehavior Members"

                      Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters

                      End Sub

                      Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As System.ServiceModel.Dispatcher.ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior

                      End Sub

                      Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As System.ServiceModel.Dispatcher.EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior        

                                    Dim inspector As New HmacVerificationInspector()

                                    endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector)    

                      End Sub

                      Public Sub Validate(endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate

                      End Sub

                      #End Region

        End Class

    HmacVerificationConfigurationSection

        Imports System.ServiceModel.Configuration    

        Imports System.ServiceModel.Description

        Namespace NamespaceHere

               Public Class HmacVerificationConfigurationSection         Inherits BehaviorExtensionElement         Implements IServiceBehavior

                        #Region "IServiceBehavior Members"

                        Public Sub AddBindingParameters(serviceDescription As ServiceDescription, serviceHostBase As System.ServiceModel.ServiceHostBase, endpoints As System.Collections.ObjectModel.Collection(Of ServiceEndpoint), bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) Implements IServiceBehavior.AddBindingParameters

                        End Sub

                        Public Sub ApplyDispatchBehavior(serviceDescription As ServiceDescription, serviceHostBase As System.ServiceModel.ServiceHostBase) Implements IServiceBehavior.ApplyDispatchBehavior

                        End Sub

                        Public Sub Validate(serviceDescription As ServiceDescription, serviceHostBase As System.ServiceModel.ServiceHostBase) Implements IServiceBehavior.Validate

                        End Sub

                       #End Region

                       Public Overrides ReadOnly Property BehaviorType() As Type            

                             Get                

                                  Return GetType(HmacVerificationBehavior)            

                            End Get       

                        End Property

                        Protected Overrides Function CreateBehavior() As Object            

                            Return New HmacVerificationBehavior()        

                         End Function

        End Class

        End Namespace

    HmacVerificationInspector

        Imports System.ServiceModel.Dispatcher    

        Imports System.ServiceModel.Channels

        Public Class HmacVerificationInspector    

                     Implements IDispatchMessageInspector

                     #Region "IDispatchMessageInspector Members"

                      Public Function AfterReceiveRequest(ByRef request As System.ServiceModel.Channels.Message, channel As System.ServiceModel.IClientChannel, instanceContext As System.ServiceModel.InstanceContext) As Object        

                             Dim buffer As MessageBuffer = request.CreateBufferedCopy(Int32.MaxValue)        

                             request = buffer.CreateMessage()        

                             Dim dupeRequest As Message = buffer.CreateMessage()

                             'ValidateHmac(dupeRequest)

                             buffer.Close()

                             Return Nothing    

                     End Function

                     Public Sub BeforeSendReply(ByRef reply As System.ServiceModel.Channels.Message, correlationState As Object)

                     End Sub

                     #End Region

                     Public Function AfterReceiveRequest1(ByRef request As Message, channel As ServiceModel.IClientChannel, instanceContext As ServiceModel.InstanceContext) As Object Implements IDispatchMessageInspector.AfterReceiveRequest

                     End Function

                     Public Sub BeforeSendReply1(ByRef reply As Message, correlationState As Object) Implements IDispatchMessageInspector.BeforeSendReply

                     End Sub    

              End Class

    IService

        Imports System.ServiceModel

        ' NOTE: You can use the "Rename" command on the context menu to change the interface name "IService" in both code and config file together.     <ServiceContract()>     Public Interface IService

        <OperationContract()>    

        Sub DoWork()

        <OperationContract()>    

        Function DoSomething(ByVal _str As String) As String

        End Interface

    And Service

        Public Class Service    

             Implements IService

        Public Sub DoWork() Implements IService.DoWork    

        End Sub

        Public Function DoSomething(ByVal _str As String) As String Implements IService.DoSomething

            Return "Message [" & _str & "]"

        End Function

        End Class

    The Web.Config file is as follows:

    <configuration>

      <system.web>

        <compilation debug="true" strict="false" explicit="true" targetFramework="4.5"/>

        <httpRuntime targetFramework="4.5"/>

      </system.web>

      <system.serviceModel>

        <extensions>

          <behaviorExtensions>

            <add name="hmacVerification"

               type="NamespaceHere.HmacVerificationConfigurationSection, NamespaceHere, 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 />   ***************COMMENT OUT THIS LINE TO MAKE WORK***************************

            </behavior>

          </endpointBehaviors>

          <serviceBehaviors>

            <behavior name="">

              <serviceMetadata httpGetEnabled="true"/>

              <serviceDebug includeExceptionDetailInFaults="false"/>

            </behavior>

          </serviceBehaviors>

        </behaviors>

        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>

      </system.serviceModel>

    </configuration>

    So, we have the example code which works perfectly if the <hmacVerification/> line is commented out in the Web.Config. As soon as it is uncommented the following happens:

    Server Error in '/DemoMessageInspector' Application.


    Configuration Error

    Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

    Parser Error Message: The type 'NamespaceHere.HmacVerificationConfigurationSection, NamespaceHere, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' registered for extension 'hmacVerification' could not be loaded.

    Source Error:

    Line 25:         <behavior name="web">
    Line 26:           <webHttp automaticFormatSelectionEnabled="true"/>
    Line 27: <hmacVerification /> 
    Line 28:         </behavior>
    Line 29:       </endpointBehaviors>


    Source File: C:\inetpub\wwwroot\DemoMessageInspector\web.config    Line: 27


    Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.18044

    So, the question is basically how should this be configured?

    Or maybe the question is, Is this the right approach to use to complete a simple task as reading a SOAP header from a WCF endpoint?

    Monday, September 30, 2013 7:12 AM

Answers

  • User-488622176 posted

    Are you sure this is correct:

    <add name="hmacVerification"
    
               type="NamespaceHere.HmacVerificationConfigurationSection, NamespaceHere, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>


    Is "NamespaceHere" the correct namespace? What assembly do you use?

    <extensions>
                <behaviorExtensions>
                    <add name="hmacVerification" type="NamespaceHere.HmacVerificationConfigurationSection, AssembleyHere, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                </behaviorExtensions>
            </extensions>

    You should replace "NamespaceHere" and "AssembleyHere" with the concrete namespace and assembly where HmacVerificationConfigurationSection is implemented.

    HTH

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, September 30, 2013 7:43 AM