10

私は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);

同じですが、認証ヘッダーが追加されていますが、サービスに到達していません。サービスがどのヘッダーを受信したかを知るにはどうすればよいですか?私はSOAPUIを使用しましたが、そのようなヘッダーをリクエストに手動で追加すると(実行前に)、サービスは適切に応答します。

4

4 に答える 4

9

最も簡単な方法は、クライアント側に追加することです:

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");

また、次の記事を確認することをお勧めします。

WCF を使用した HTTP 要求に承認ヘッダーがありません

wsHttpBinding を使用した WCF サービス - HTTP 要求ヘッダーの操作

于 2013-01-31T08:58:49.453 に答える
4

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;
    }
于 2013-01-31T09:31:58.717 に答える
2

これが遅れていることはわかっていますが、この投稿に出くわしたので、これをもう一度思い出す必要がある場合に備えて、これに記入することにしました. これは私のために働いた:

  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()
    
于 2015-01-22T20:40:53.760 に答える
0

ソリューションの問題は、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);
}
于 2014-11-26T09:40:22.133 に答える