我创建了一个WCF REST服务,我正在尝试进行自定义身份验证(因为它应该适用于http和https)。
我正在使用客户服务授权管理器来检查和验证授权标题。
当我使用Fiddler调用服务并通过请求传递Authorization标头时,我在服务授权管理器中正确接收它。
但是当我在WCFChannelFactory上设置凭据时,我没有收到服务中的Authorization标头。我希望授权标题应该由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>
我正在使用客户服务授权管理器来检查和验证授权标题。
答案 0 :(得分: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()
答案 1 :(得分:0)
对后人来说,这是我发现这个问题的解决方案:
首先,在您的客户端中取出<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-to-a-call-http-version.aspx