我已经创建了WCF REST服务,并且我正在尝试进行自定义身份验证(因为它应该在HTTP和HTTPS上使用)。
我正在使用Custome服务授权经理检查和验证授权标题。
当我使用Fiddler调用服务并通过请求通过授权标头时,我将在服务授权管理器中正确收到。
但是,当我在WCFChannelfactory上设置凭据时,我没有在服务中收到授权标题。我希望WCFCHANNELFACTORY应该创建授权标题,并通过请求通过。
客户端代码如下:
WebChannelFactory<IDataService> factory = new WebChannelFactory<IDataService>("DataServiceClient1");
factory.Credentials.UserName.UserName = "user1";
factory.Credentials.UserName.Password = "password123";
var client = factory.CreateChannel();
var data = client.GetData1("Microsoft");
Console.WriteLine("Get response : {0}", data);
客户端服务配置如下:
<system.serviceModel>
<client>
<endpoint address="http://localhost.fiddler:50179/DataService.svc"
binding="webHttpBinding" bindingConfiguration="auth"
contract="RESTWebServiceSpike.IDataService"
behaviorConfiguration="web"
name="DataServiceClient1">
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="auth">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
我的服务配置如下:
<services>
<service name="RESTWebServiceSpike.DataService" behaviorConfiguration="DataServiceBehaviour">
<endpoint address="" binding="webHttpBinding"
contract="RESTWebServiceSpike.IDataService" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DataServiceBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true"/>
<serviceAuthorization serviceAuthorizationManagerType="RESTWebServiceImpl.AuthorizationManager, RESTWebServiceImpl" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
我正在使用Custome服务授权经理检查和验证授权标题。
我知道这已经晚了,但是我遇到了这篇文章,因此决定填写这一点,以防我需要再次记住这一点。这对我有用:
-
创建消息检查器:
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()
对于后代,这是我发现的解决方案:
首先,在客户端中取出您的<service></service>
标签。
然后,您需要在OperationContextScope中包装呼叫,并在其中添加标头。例如:
using (new OperationContextScope((IClientChannel)client))
{
HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();
string credentials = string.Format("{0}:{1}", _username, _password);
requestProperty.Headers["Authorization"] = string.Format("Basic {0}", Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(credentials)));
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestProperty;
data = client.GetData1();
}
这是MSDN的参考点:
http://blogs.msdn.com/b/drnick/archive/2008/07/08/adding-headers-headers-to-a-call-http-version.aspx