Как добавить пользовательский заголовок Http для веб-службы С#, использующий веб-службу Axis 1.4
Я пытаюсь написать клиент веб-службы в С#, который является веб-сервисом Java Axis 1.4.
Для обслуживания оси требуется заголовок Авторизация: базовое Base64EncodedToken в заголовках HTTP.
Я не могу найти способ установить этот заголовок стандартными способами использования веб-сервисов на visual studio.net, например, с обычным WSDL-реферированием и с WSE3.0
Я не могу использовать WCF, поскольку проект разработан с использованием .net 2.0.
Есть ли способ сделать это?
Ответы
Ответ 1
Кажется, что оригинальный автор нашел свое решение, но для тех, кто получает здесь возможность добавлять фактические пользовательские заголовки, если у вас есть доступ к модному сгенерированному коду протокола, вы можете переопределить 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
, если хотите войти в него.
Ответ 2
Мы говорим о 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 с базовым auth через http или https.
Я надеюсь, что это поможет кому-то, потому что у меня возникли серьезные проблемы с поиском решения в Интернете.
Ответ 3
Если вы хотите отправить пользовательский заголовок HTTP (а не заголовок SOAP), вам нужно использовать класс HttpWebRequest, который будет выглядеть так:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("Authorization", token);
Вы не можете добавлять заголовки HTTP, используя созданный visual studio прокси-сервер, который может быть настоящей болью.
Ответ 4
Я нахожу этот код и решаю свою проблему.
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
Вместо того, чтобы модифицировать автоматически сгенерированный код или обертывать каждый вызов в двойном коде, вы можете вводить свои собственные 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-заголовок.
Ответ 6
См. Создание безопасных приложений ASP.NET: аутентификация, авторизация и безопасная связь и поиск по "Использование определенных учетных данных". Также см. Документы MSDN для Класс CredentialCache.
Ответ 7
Вот что сработало для меня:
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 не принимала запрос, и я получал несанкционированную ошибку.