如何在WCF中向请求添加授权标头?

我正在使用Windows窗体应用程序,并且需要调用WCF服务。 我需要在请求发送到服务之前向请求添加标头(授权 – 自定义)。 我也有一个自定义检查器类。 我尝试了以下但是服务没有被调用,不知何故,它返回一个exception。

public object BeforeSendRequest(ref Message request, IClientChannel channel) { MessageHeader header = MessageHeader.CreateHeader("Authorization", "", "Basic Y19udGk6Q29udGlfQjNTVA=="); OperationContext.Current.OutgoingMessageHeaders.Add(header); HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty(); httpRequestProperty.Headers.Add("Authorization", "Basic Y19udGk6Q29udGlfQjNTVA=="); httpRequestProperty.Headers.Add(HttpRequestHeader.UserAgent, "Continental"); OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty; sentMessages.Add(request.ToString()); return null; } 

我也尝试过这样一个最简单的方法:

 MessageHeader header = MessageHeader.CreateHeader("Authorization", "", "Basic Y19udGk6Q29udGlfQjNTVA=="); request.Headers.Add(header); 

但它是相同的,添加了授权标题,但它没有到达服务,我怎么知道服务接收到什么标题? 当我在请求中手动添加这样的头文件(运行之前)时,我使用SOAP UI和服务响应很好。

最简单的方法是在客户端添加它

 using (MyServ.ServiceClient proxy = new MyServ.ServiceClient()) { using (new System.ServiceModel.OperationContextScope(proxy.InnerChannel)) { MessageHeader head = MessageHeader.CreateHeader("Authorization", "http://yournamespace.com/v1", data); OperationContext.Current.OutgoingMessageHeaders.Add(head); } } 

在服务器端检索它

 string auth = OperationContext.Current.IncomingMessageHeaders. GetHeader("Authorization", "http://mynamespace.com/v1"); 

我还建议你查看这些文章:

使用WCF的Http请求中缺少授权标头

使用wsHttpBinding的WCF服务 – 操作HTTP请求标头

如果您的BeforeSend方法存在一些问题,这是我在为某些Web服务调用添加身份validation时实现它的方式。

 private const string Authorization = "Authorization"; public object BeforeSendRequest(ref Message request, IClientChannel channel) { object httpRequestMessageObject; if (request.Properties.TryGetValue( HttpRequestMessageProperty.Name, out httpRequestMessageObject)) { var httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty; if (string.IsNullOrWhiteSpace(httpRequestMessage.Headers[Authorization])) { httpRequestMessage.Headers[Authorization] = "Basic Y19udGk6Q29udGlfQjNTVA=="; } } else { var httpRequestMessage = new HttpRequestMessageProperty(); httpRequestMessage.Headers.Add(Authorization, "Basic Y19udGk6Q29udGlfQjNTVA=="); request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage); } return null; } 

我知道这已经很晚了,但是我跑过这个post所以决定填写这个,以防万一我需要再次记住这个。 这对我有用:

  1. 创建消息检查器:

     Public Class AuthenticationHeader Implements IClientMessageInspector Private itsUser As String Private itsPass As String Public Sub New(ByVal user As String, ByVal pass As String) itsUser = user itsPass = pass End Sub Public Sub AfterReceiveReply(ByRef reply As Message, correlationState As Object) Implements IClientMessageInspector.AfterReceiveReply Console.WriteLine("Received the following reply: '{0}'", reply.ToString()) End Sub Public Function BeforeSendRequest(ByRef request As Message, channel As IClientChannel) As Object Implements IClientMessageInspector.BeforeSendRequest Dim hrmp As HttpRequestMessageProperty = request.Properties("httpRequest") Dim encoded As String = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(itsUser + ":" + itsPass)) hrmp.Headers.Add("Authorization", "Basic " + encoded) Return request End Function End Class 
  2. 写下行为:

     Public Class AuthenticationHeaderBehavior Implements IEndpointBehavior Private ReadOnly itsUser As String Private ReadOnly itsPass As String Public Sub New(ByVal user As String, ByVal pass As String) MyBase.New() itsUser = user itsPass = pass End Sub Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters End Sub Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior clientRuntime.MessageInspectors.Add(New AuthenticationHeader(itsUser, itsPass)) End Sub Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior End Sub Public Sub Validate(endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate End Sub End Class 
  3. 将其添加到您的终端:

      Dim binding As New WebHttpBinding(WebHttpSecurityMode.Transport) binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None ChlFactory = New WebChannelFactory(Of IMyServiceContract)(binding, New Uri(url)) ChlFactory.Endpoint.Behaviors.Add(New WebHttpBehavior()) ChlFactory.Endpoint.Behaviors.Add(New AuthenticationHeaderBehavior(user, pass)) Channel = ChlFactory.CreateChannel() 

您的解决方案的问题是它将添加HTTP标头。 但是,您需要的是SOAP标头。 这可以这样做……

 using(new OperationContextScope(client.InnerChannel)) { // Add a SOAP Header to an outgoing request MessageHeader aMessageHeader = MessageHeader.CreateHeader("UserInfo", "http://tempuri.org", userInfo); OperationContext.Current.OutgoingMessageHeaders.Add(aMessageHeader); }