web-dev-qa-db-ja.com

Axis 1.4 Webサービスを使用するC#WebサービスクライアントのカスタムHttpヘッダーを追加する方法

WebサービスがJava Axis1.4。AxisサービスにはHTTPヘッダーのAuthorization:Basic Base64EncodedTokenヘッダー値が必要通常のWSDLで生成された参照やWSE3.0のように、Visual Studio.netでWebサービスを使用する標準的な方法でこのヘッダーを設定する方法が見つかりません

プロジェクトは.net 2.0を使用して開発されているため、WCFは使用できません。

これを行う方法はありますか?

46
UmutKa

元の作者が解決策を見つけたようですが、ここに実際のカスタムヘッダーを追加しようとしている人は、生成されたプロトコルコードをmodにアクセスできる場合、GetWebRequestをオーバーライドできます。

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
  System.Net.WebRequest request = base.GetWebRequest(uri);
  request.Headers.Add("myheader", "myheader_value");
  return request;
}

ステップインする場合は、DebuggerStepThroughAttribute属性を必ず削除してください。

47
user334291

ここでWCFについて話していますか?サービスコールがhttp認証ヘッダーを追加しないという問題があり、このステートメントにコールをラップすると問題が解決しました。

  using (OperationContextScope scope = new OperationContextScope(RefundClient.InnerChannel))
  {
            var httpRequestProperty = new HttpRequestMessageProperty();
            httpRequestProperty.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " +
            Convert.ToBase64String(Encoding.ASCII.GetBytes(RefundClient.ClientCredentials.UserName.UserName + ":" +
            RefundClient.ClientCredentials.UserName.Password));
            OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;

            PaymentResponse = RefundClient.Payment(PaymentRequest);
   }

これは、SOAP httpまたはhttps経由の基本認証を使用した.NET経由のIBM ESBへの呼び出しを実行していました。

オンラインで解決策を見つけるのに大きな問題があったので、これが誰かの助けになることを願っています。

25
Simon RC

自動生成されたコードを改造したり、すべての呼び出しを重複したコードでラップしたりする代わりに、カスタムメッセージインスペクターを追加してカスタムHTTPヘッダーを挿入できます。

public class CustomMessageInspector : IClientMessageInspector
{
    readonly string _authToken;

    public CustomMessageInspector(string authToken)
    {
        _authToken = authToken;
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        var reqMsgProperty = new HttpRequestMessageProperty();
        reqMsgProperty.Headers.Add("Auth-Token", _authToken);
        request.Properties[HttpRequestMessageProperty.Name] = reqMsgProperty;
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState)
    { }
}


public class CustomAuthenticationBehaviour : IEndpointBehavior
{
    readonly string _authToken;

    public CustomAuthenticationBehaviour (string authToken)
    {
        _authToken = authToken;
    }
    public void Validate(ServiceEndpoint endpoint)
    { }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    { }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    { }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add(new CustomMessageInspector(_authToken));
    }
}

また、クライアントクラスをインスタンス化するときに、単にビヘイビアとして追加できます。

this.Endpoint.EndpointBehaviors.Add(new CustomAuthenticationBehaviour("Auth Token"));

これにより、すべての発信サービスコールがカスタムHTTPヘッダーを持つようになります。

7
Saeb Amini

カスタムHTTPヘッダー(SOAPヘッダーではない)を送信する場合は、コードが次のように見えるHttpWebRequestクラスを使用する必要があります。

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("Authorization", token);

Visual Studioが生成したプロキシを使用してHTTPヘッダーを追加することはできません。

7
John Hunter

このコードを見つけて、問題を解決しています。

http://arcware.net/setting-http-header-authorization-for-web-services/

protected override WebRequest GetWebRequest(Uri uri)
{
    // Assuming authValue is set from somewhere, such as the config file
    HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
    request.Headers.Add("Authorization", string.Format("Basic {0}", authValue));
    return request;
}
5

user334291の答えは私にとって命の恩人でした。 OPが元々意図していたこと(私が最終的に使用したこと)を追加する方法を追加したいだけです。

生成されたWebサービスコードでGetWebRequest関数をオーバーライドします。

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
    System.Net.WebRequest request = base.GetWebRequest(uri);          
    string auth = "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(this.Credentials.GetCredential(uri, "Basic").UserName + ":" + this.Credentials.GetCredential(uri, "Basic").Password));
    request.Headers.Add("Authorization", auth);
    return request;
}

webサービスを呼び出す前に資格情報を設定します。

  client.Credentials = new NetworkCredential(user, password);       
1
Tiago Martins

ここに私のために働いたものがあります:

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
        HttpWebRequest request;
        request = (HttpWebRequest)base.GetWebRequest(uri);
        NetworkCredential networkCredentials =
        Credentials.GetCredential(uri, "Basic");
        if (networkCredentials != null)
        {
            byte[] credentialBuffer = new UTF8Encoding().GetBytes(
            networkCredentials.UserName + ":" +
            networkCredentials.Password);
            request.Headers["Authorization"] =
            "Basic " + Convert.ToBase64String(credentialBuffer);
            request.Headers["Cookie"] = "BCSI-CS-2rtyueru7546356=1";
            request.Headers["Cookie2"] = "$Version=1";
        }
        else
        {
            throw new ApplicationException("No network credentials");
        }
        return request;
}

このプロパティを設定することを忘れないでください:

service.Credentials = new NetworkCredential("username", "password");  

Javaサービスがリクエストを受け付けておらず、不正なエラーが発生したため、CookieとCookie2はヘッダーに設定されています。

0
Attiq Rehman