我正在开发一个Windows窗体应用程序,并且需要调用一个WCF服务。我需要在请求发送到服务之前为请求添加标头(授权 - 自定义)。我也有一个自定义检查器类。我试过以下但是服务没有以某种方式被调用,并且它返回一个异常。
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
MessageHeader header = MessageHeader.CreateHeader("Authorization", "", "Basic Y19udGk6Q29udGlfQjNTVA==");
OperationContext.Current.OutgoingMessageHeaders.Add(header);
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers.Add("Authorization", "Basic Y19udGk6Q29udGlfQjNTVA==");
httpRequestProperty.Headers.Add(HttpRequestHeader.UserAgent, "Continental");
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
sentMessages.Add(request.ToString());
return null;
}
我也尝试过最简单的方法:
MessageHeader header = MessageHeader.CreateHeader("Authorization", "", "Basic Y19udGk6Q29udGlfQjNTVA==");
request.Headers.Add(header);
但是它是相同的,添加了授权标题但是它没有到达服务,我怎么知道服务接收到什么标题?当我在请求中手动添加这样的标题(运行之前)时,我使用SOAP UI和服务响应很好。
答案 0 :(得分:8)
最简单的方法是在客户端添加:
using (MyServ.ServiceClient proxy = new MyServ.ServiceClient())
{
using (new System.ServiceModel.OperationContextScope(proxy.InnerChannel))
{
MessageHeader head = MessageHeader.CreateHeader("Authorization", "http://yournamespace.com/v1", data);
OperationContext.Current.OutgoingMessageHeaders.Add(head);
}
}
和在服务器端检索:
string auth = OperationContext.Current.IncomingMessageHeaders.
GetHeader<string>("Authorization", "http://mynamespace.com/v1");
我还建议您查看这些文章:
Authorization Header is missing in Http request using WCF
WCF Service with wsHttpBinding - Manipulating HTTP request headers
答案 1 :(得分:3)
如果您的BeforeSend方法存在问题,这是我在为某些网络服务调用添加身份验证时实现的方法。
private const string Authorization = "Authorization";
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
object httpRequestMessageObject;
if (request.Properties.TryGetValue(
HttpRequestMessageProperty.Name, out httpRequestMessageObject))
{
var httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
if (string.IsNullOrWhiteSpace(httpRequestMessage.Headers[Authorization]))
{
httpRequestMessage.Headers[Authorization] = "Basic Y19udGk6Q29udGlfQjNTVA==";
}
}
else
{
var httpRequestMessage = new HttpRequestMessageProperty();
httpRequestMessage.Headers.Add(Authorization, "Basic Y19udGk6Q29udGlfQjNTVA==");
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
return null;
}
答案 2 :(得分:1)
我知道这已经很晚了,但我遇到了这个帖子所以决定填写这个,以防万一我需要再次记住这个。这对我有用:
创建消息检查器:
Public Class AuthenticationHeader
Implements IClientMessageInspector
Private itsUser As String
Private itsPass As String
Public Sub New(ByVal user As String, ByVal pass As String)
itsUser = user
itsPass = pass
End Sub
Public Sub AfterReceiveReply(ByRef reply As Message, correlationState As Object) Implements IClientMessageInspector.AfterReceiveReply
Console.WriteLine("Received the following reply: '{0}'", reply.ToString())
End Sub
Public Function BeforeSendRequest(ByRef request As Message, channel As IClientChannel) As Object Implements IClientMessageInspector.BeforeSendRequest
Dim hrmp As HttpRequestMessageProperty = request.Properties("httpRequest")
Dim encoded As String = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(itsUser + ":" + itsPass))
hrmp.Headers.Add("Authorization", "Basic " + encoded)
Return request
End Function
End Class
写下行为:
Public Class AuthenticationHeaderBehavior
Implements IEndpointBehavior
Private ReadOnly itsUser As String
Private ReadOnly itsPass As String
Public Sub New(ByVal user As String, ByVal pass As String)
MyBase.New()
itsUser = user
itsPass = pass
End Sub
Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As BindingParameterCollection) Implements IEndpointBehavior.AddBindingParameters
End Sub
Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As ClientRuntime) Implements IEndpointBehavior.ApplyClientBehavior
clientRuntime.MessageInspectors.Add(New AuthenticationHeader(itsUser, itsPass))
End Sub
Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As EndpointDispatcher) Implements IEndpointBehavior.ApplyDispatchBehavior
End Sub
Public Sub Validate(endpoint As ServiceEndpoint) Implements IEndpointBehavior.Validate
End Sub
End Class
将其添加到您的终端:
Dim binding As New WebHttpBinding(WebHttpSecurityMode.Transport)
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
ChlFactory = New WebChannelFactory(Of IMyServiceContract)(binding, New Uri(url))
ChlFactory.Endpoint.Behaviors.Add(New WebHttpBehavior())
ChlFactory.Endpoint.Behaviors.Add(New AuthenticationHeaderBehavior(user, pass))
Channel = ChlFactory.CreateChannel()
答案 3 :(得分:0)
您的解决方案的问题是它会添加HTTP标头。但是,您需要的是SOAP标头。这可以这样做......
using(new OperationContextScope(client.InnerChannel))
{
// Add a SOAP Header to an outgoing request
MessageHeader aMessageHeader = MessageHeader.CreateHeader("UserInfo", "http://tempuri.org", userInfo);
OperationContext.Current.OutgoingMessageHeaders.Add(aMessageHeader);
}