Как добавить пользовательский заголовок Http для клиента веб-службы C #, использующего веб-службу Axis 1.4 - PullRequest
44 голосов
/ 22 мая 2009

Я пытаюсь написать клиент веб-сервиса на c #, который веб-сервисом является Java Axis 1.4. Службе Axis требуется значение заголовка Authorization: Basic Base64EncodedToken в заголовках HTTP. Я не могу найти способ установить этот заголовок стандартными способами использования веб-сервисов в visual studio.net, как обычные ссылки, генерируемые WSDL, так и с WSE3.0

Я не могу использовать WCF, так как проект разрабатывается с использованием .net 2.0.

Есть ли способ сделать это?

Ответы [ 7 ]

46 голосов
/ 06 мая 2010

Кажется, что оригинальный автор нашел свое решение, но для всех, кто хочет сюда добавить настоящие пользовательские заголовки, если у вас есть доступ к моду сгенерированного кода протокола, вы можете переопределить 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, если хотите войти в него.

25 голосов
/ 11 ноября 2009

Мы говорим здесь 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 в IBM ESB через .NET с базовой аутентификацией через http или https.

Надеюсь, это кому-нибудь поможет, потому что у меня были серьезные проблемы с поиском решения в Интернете.

7 голосов
/ 06 марта 2017

Вместо того, чтобы модифицировать автоматически сгенерированный код или упаковывать каждый вызов в дублирующийся код, вы можете добавить свои собственные заголовки 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 голосов
/ 22 мая 2009

Если вы хотите отправить пользовательский заголовок HTTP (не заголовок SOAP), вам нужно использовать класс HttpWebRequest, код будет выглядеть так:

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

Вы не можете добавлять заголовки HTTP, используя прокси, сгенерированный Visual Studio, что может быть настоящей болью.

5 голосов
/ 11 августа 2010

Я нашел этот код и решил мою проблему.

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;
}
1 голос
/ 19 февраля 2018

user334291 ответ был спасением для меня. Просто хочу добавить, как вы можете добавить то, что изначально предназначалось для ОП (то, что я в итоге использовал):

Переопределение функции 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;
}

и установка учетных данных перед вызовом веб-службы:

  client.Credentials = new NetworkCredential(user, password);       
0 голосов
/ 02 августа 2013

Вот что у меня сработало:

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-сервис не принимал запрос, и я получал несанкционированную ошибку.

...