我正在尝试在c#中编写Web服务客户端,其中webservice是Java Axis 1.4。 Axis服务需要HTTP标头中的授权:基本Base64EncodedToken 标头值。 我无法找到一种方法来在visual studio.net中以不同的方式设置此标头,就像正常的WSDL生成引用一样,也不能使用WSE3.0
我不能使用WCF,因为项目是使用.net 2.0开发的。
有没有办法做到这一点?
答案 0 :(得分:46)
原作者似乎找到了他们的解决方案,但对于其他任何想要添加实际自定义标头的人来说,如果您有权访问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
属性,请务必删除它。
答案 1 :(得分:25)
我们在这里谈论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。
我希望这可以帮助别人,因为我在网上找到解决方案存在大量问题。
答案 2 :(得分:7)
如果要发送自定义HTTP标头(而不是SOAP标头),则需要使用代码看起来像的HttpWebRequest类:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("Authorization", token);
您无法使用visual studio生成的代理添加HTTP标头,这可能是一个真正的痛苦。
答案 3 :(得分:6)
您可以通过添加自定义消息检查器来注入自定义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标头。
答案 4 :(得分:5)
我找到了这段代码并解决了我的问题。
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 :(得分:1)
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;
}
并在调用webservice之前设置凭据:
client.Credentials = new NetworkCredential(user, password);
答案 6 :(得分:0)
这对我有用:
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服务不接受请求而我收到了未经授权的错误。