如何将授权标头添加到 WCF 中的请求
本文关键字:WCF 请求 添加 授权 权标 | 更新日期: 2023-09-27 17:57:00
我正在开发一个 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,当我在请求中手动添加这样的标头时(在运行之前),服务响应良好。
最简单的方法是在客户端添加它:
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");
我还建议您查看以下文章:
使用 WCF 的 Http 请求中缺少授权标头
使用 wsHttpBinding 的 WCF 服务 - 操作 HTTP 请求标头
如果您的 BeforeSend 方法存在问题,这就是我在向某些 Web 服务调用添加身份验证时实现它的方式。
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;
}
我知道
这已经晚了,但我遇到了这篇文章,所以我决定填写这篇文章,以防我需要再次记住这一点。这对我有用:
创建邮件检查器:
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()
您的解决方案的问题在于它会添加一个 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);
}