2014-01-21 158 views
1

我已经创建了WCF REST服务,并且正在尝试执行自定义身份验证(因为它应该在http和https上工作)。WCF REST基本身份验证 - 无法设置授权标头

我正在使用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服务授权管理器检查并验证授权标题。

回答

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

1

我知道这是晚了,但我跑过这个职位如此决定,以填补这,万一我所需要的再次记住这一点。这为我工作:

  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 
    
  2. 写行为:

    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 
    
  3. 将它添加到您的端点:

    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()