如何为使用 Axis 1.4 Web 服务的 C# Web 服务客户端添加自定义 Http 标头

发布于 2024-07-20 06:41:38 字数 290 浏览 10 评论 0原文

我正在尝试用 C# 编写一个 Web 服务客户端,其中 Web 服务是 Java Axis 1.4。 Axis 服务需要 HTTP 标头中的 Authorization: Basic Base64EncodedToken 标头值。 我找不到在 Visual Studio.net 中使用 Web 服务的标准方式设置此标头的方法,例如正常的 WSDL 生成的引用,也无法使用 WSE3.0

我无法使用 WCF,因为该项目是使用 .net 2.0 开发的。

有什么办法可以做到这一点吗?

I'm trying to write a web service client in c# which the webservice is Java Axis 1.4.
Axis service requires the Authorization: Basic Base64EncodedToken header value in the HTTP Headers.
I can't find a way to set this header in standart ways of consuming web services in visual studio.net, like normal WSDL generated refernce nor with WSE3.0

I can't use WCF as the project is developed using .net 2.0.

Is there any way to do this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

枕花眠 2024-07-27 06:41:39

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

user334291's answer was a life saver for me. Just want to add how you can add what the OP originally intended to do (what I ended up using):

Overriding the GetWebRequest function on the generated webservice code:

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

and setting the credentials before calling the webservice:

  client.Credentials = new NetworkCredential(user, password);       
剩一世无双 2024-07-27 06:41:39

这对我有用:

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

Cookie 和 Cookie2 在标头中设置,因为 java 服务不接受请求,并且我收到未经授权的错误。

Here is what worked for me:

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

Don't forget to set this property:

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

Cookie and Cookie2 are set in header because java service was not accepting the request and I was getting Unauthorized error.

美人骨 2024-07-27 06:41:38

看来原作者已经找到了他们的解决方案,但对于任何其他想要添加实际自定义标头的人来说,如果您有权修改生成的协议代码,您可以覆盖 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 属性。

It seems the original author has found their solution, but for anyone else who gets here looking to add actual custom headers, if you have access to mod the generated Protocol code you can override GetWebRequest:

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

Make sure you remove the DebuggerStepThroughAttribute attribute if you want to step into it.

千笙结 2024-07-27 06:41:38

我们在这里谈论 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);
   }

这是通过 .NET 对 IBM ESB 运行 SOAP 调用,并通过 http 或 https 进行基本身份验证。

我希望这可以帮助别人,因为我在网上寻找解决方案时遇到了很多问题。

Are we talking WCF here? I had issues where the service calls were not adding the http authorization headers, wrapping any calls into this statement fixed my issue.

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

This was running SOAP calls to IBM ESB via .NET with basic auth over http or https.

I hope this helps someone out because I had massive issues finding a solution online.

荒人说梦 2024-07-27 06:41:38

您可以通过添加自定义消息检查器来注入自定义 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 标头。

Instead of modding the auto-generated code or wrapping every call in duplicate code, you can inject your custom HTTP headers by adding a custom message inspector, it's easier than it sounds:

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

And when instantiating your client class you can simply add it as a behavior:

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

This will make every outgoing service call to have your custom HTTP header.

长梦不多时 2024-07-27 06:41:38

如果您想发送自定义 HTTP 标头(而不是 SOAP 标头),那么您需要使用 HttpWebRequest 类,代码如下所示:

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

您无法使用 Visual Studio 生成的代理添加 HTTP 标头,这可能是一个真正的痛苦。

If you want to send a custom HTTP Header (not a SOAP Header) then you need to use the HttpWebRequest class the code would look like:

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

You cannot add HTTP headers using the visual studio generated proxy, which can be a real pain.

鹤舞 2024-07-27 06:41:38

我找到这段代码并解决了我的问题。

http://arcware.net/setting-http-header-authorization-用于网络服务/

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

I find this code and is resolve my problem.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文