Beaucoup pensent qu'il n'est pas possible de passer un cookie d'identification à un WCF Service.
Les méthodes suivantes démontrent que c'est possible.
Méthode 1 :
Tout d'abord mettez le code suivant dans le constructeur de votre service :
Public Sub New()
Thread.CurrentPrincipal = HttpContext.Current.User
End Sub
Voici comment appeller la méthode de votre service :
Dim ws As New ServiceWeb.ServiceContractClient
Dim valid = Membership.ValidateUser("Jacques", "MonMotDePasse")
Dim identity = TryCast(Thread.CurrentPrincipal.Identity, ClientFormsIdentity)
Using ocs = New OperationContextScope(TryCast(ws.InnerChannel, IContextChannel))
Dim ch = identity.AuthenticationCookies.GetCookieHeader(ws.Endpoint.ListenUri)
Dim rmp As New HttpRequestMessageProperty()
rmp.Headers(HttpRequestHeader.Cookie) = ch
Dim col = ws.Endpoint.Binding.CreateBindingElements()
Dim transport = col.Find(Of HttpTransportBindingElement)()
transport.AllowCookies = True
ws.Endpoint.Binding = New CustomBinding(col)
OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, rmp)
ws.MaMethode(MesParametres)
End Using
Méthode 2 :
Tapez une dizaine de lignes de codes à chaque fois que vous devez appeller une méthode de votre WCF service ce n'est pas très pratique. Voici donc comment automatiser l'ajout d'un cookie dans l'entête.
Tout d'abord il nous faut créer 2 classes
CookieBehavior et
CookieMessageInspector qui implémentent respectivement
IEndPointBehavior et
IClientMessageInspector.
Imports System.ServiceModel.Description
Imports System.ServiceModel.Dispatcher
Imports System.ServiceModel.Channels
Imports System.ServiceModel
Imports System.Threading
Imports System.Web.ClientServices
Imports System.Net
Public Class CookieBehavior
Implements IEndpointBehavior
Private cookie As String
Public Sub New(cookie As String)
Me.cookie = cookie
End Sub
Public Sub AddBindingParameters(serviceEndpoint As ServiceEndpoint, bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters
End Sub
Public Sub ApplyClientBehavior(serviceEndpoint As ServiceEndpoint, behavior As System.ServiceModel.Dispatcher.ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior
behavior.MessageInspectors.Add(New CookieMessageInspector(cookie))
End Sub
Public Sub ApplyDispatchBehavior(serviceEndpoint As ServiceEndpoint, endpointDispatcher As System.ServiceModel.Dispatcher.EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior
End Sub
Public Sub Validate(serviceEndpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate
End Sub
End Class
Public Class CookieMessageInspector
Implements IClientMessageInspector
Private cookie As String
Public Sub New(cookie As String)
Me.cookie = cookie
End Sub
Public Sub AfterReceiveReply(ByRef reply As System.ServiceModel.Channels.Message, correlationState As Object) Implements IClientMessageInspector.AfterReceiveReply
End Sub
Public Function BeforeSendRequest(ByRef request As System.ServiceModel.Channels.Message, channel As System.ServiceModel.IClientChannel) As Object Implements IClientMessageInspector.BeforeSendRequest
Dim httpRequestMessage As HttpRequestMessageProperty
Dim httpRequestMessageObject As Object = Nothing
If request.Properties.TryGetValue(HttpRequestMessageProperty.Name, httpRequestMessageObject) Then
httpRequestMessage = TryCast(httpRequestMessageObject, HttpRequestMessageProperty)
If String.IsNullOrEmpty(httpRequestMessage.Headers("Cookie")) Then
httpRequestMessage.Headers("Cookie") = Cookie
End If
Else
httpRequestMessage = New HttpRequestMessageProperty()
httpRequestMessage.Headers.Add("Cookie", Cookie)
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage)
End If
Return Nothing
End Function
End Class
Maintenant il suffit de taper 2 lignes pour créer votre WCF Service avec son Cookie d'authentification en entête.
Dim ws As New ServiceWeb.ServiceContractClient
ws.Endpoint.Behaviors.Add(New CookieBehavior(DirectCast(Thread.CurrentPrincipal.Identity, ClientFormsIdentity).AuthenticationCookies.GetCookieHeader(ws.Endpoint.ListenUri)))