Answered by:
WCF Message Interceptor SOAP

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