Comment ajouter un en-tête Http personnalisé pour C# Web Service Client Consumer Axis 1.4 Web service

j'essaie d'écrire un client de service web en c# dont le webservice est Java Axis 1.4. Le service Axis nécessite le Autorisation: Base64encodedtoken valeur de l'en-tête dans les en-têtes HTTP. Je ne peux pas trouver un moyen de mettre cet en-tête dans des façons standart de consommer des services web en visuel studio.net, comme la référence générée par WSDL normale nor avec WSE3.0

Je ne peux pas utiliser WCF car le projet est développé en utilisant .net 2.0.

Est-il possible de faire cela ?

43
demandé sur John Saunders 2009-05-22 17:16:33

7 réponses

il semble que l'auteur d'origine a trouvé leur solution, mais pour quiconque vient ici à la recherche d'ajouter des en-têtes personnalisés, si vous avez accès à mod le code de protocole généré, vous pouvez outrepasser GetWebRequest:

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

assurez-vous d'enlever le DebuggerStepThroughAttribute attribut si vous voulez y entrer.

44
répondu user334291 2012-09-03 16:59:58

est-ce QU'on parle de la FMC ici? J'ai eu des problèmes où les appels de service n'ajoutaient pas les en-têtes d'autorisation http, enveloppant tous les appels dans cette déclaration a réglé mon problème.

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

ceci exécutait des appels SOAP à IBM ESB via .NET avec l'auth de base sur http ou https.

j'espère que cela aide quelqu'un parce que j'ai eu des problèmes énormes à trouver une solution en ligne.

25
répondu Simon RC 2016-01-14 06:06:13

si vous voulez envoyer un en-tête HTTP personnalisé (pas un en-tête SOAP), alors vous devez utiliser la classe HttpWebRequest à laquelle le code ressemblerait:

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

Vous ne pouvez pas ajouter des en-têtes HTTP en utilisant le proxy généré par visual studio, ce qui peut être une vraie douleur.

7
répondu John Hunter 2009-05-22 13:43:19

au lieu de modder le code généré automatiquement ou d'envelopper chaque appel dans du code dupliqué, vous pouvez injecter vos en-têtes HTTP personnalisés en ajoutant un inspecteur de messages personnalisés, c'est plus facile que cela ne semble:

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

et lors de l'instanciation de votre classe client vous pouvez simplement l'ajouter comme un behavior:

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

ceci fera chaque appel de service sortant pour avoir votre en-tête HTTP personnalisé.

6
répondu Saeb Amini 2017-06-08 06:09:16

je trouve ce code et résout mon problème.

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
répondu Valdemar Carneiro 2011-09-01 22:45:33

user334291 la réponse était un sauveur de vie pour moi. Veux juste ajouter que la façon dont vous pouvez ajouter ce que l'OP a l'origine destiné à faire (ce que j'ai utilisé):

suppression de la fonction GetWebRequest du code webservice généré:

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

et paramétrer les informations d'identification avant d'appeler le webservice:

  client.Credentials = new NetworkCredential(user, password);       
1
répondu Tiago Martins 2018-02-19 16:11:59

Voici ce qui a fonctionné pour moi:

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

N'oubliez pas de définir cette propriété:

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

Cookie et Cookie2 sont définis dans l'en-tête parce que le service java n'acceptait pas la requête et que je recevais une erreur non autorisée.

0
répondu Attiq Rehman 2013-08-01 23:14:04