【问题标题】:How can I add authorization header to the request in WCF?如何向 WCF 中的请求添加授权标头?
【发布时间】:2013-01-31 08:40:36
【问题描述】:

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

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 并且服务响应良好。

【问题讨论】:

    标签: c# winforms wcf header


    【解决方案1】:

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

    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<string>("Authorization", "http://mynamespace.com/v1");
    

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

    Authorization Header is missing in Http request using WCF

    WCF Service with wsHttpBinding - Manipulating HTTP request headers

    【讨论】:

      【解决方案2】:

      如果您的 BeforeSend 方法有问题,这就是我在向某些 Web 服务调用添加身份验证时的实现方式。

      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;
          }
      

      【讨论】:

        【解决方案3】:

        我知道这已经晚了,但我偶然发现了这篇文章,所以决定填写这个,以防我需要再次记住这一点。这对我有用:

        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()
          

        【讨论】:

        • Dim hrmp As HttpRequestMessageProperty = request.Properties("httpRequest") => 名为 httpRequest 的属性不存在。
        【解决方案4】:

        您的解决方案的问题在于它会添加一个 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);
        }
        

        【讨论】:

          猜你喜欢
          • 2020-03-29
          • 2017-01-04
          • 2014-12-28
          • 1970-01-01
          • 1970-01-01
          • 2015-05-17
          • 2020-10-11
          • 2019-01-10
          • 1970-01-01
          相关资源
          最近更新 更多