【问题标题】:WCF REST Basic Authentication - not able to set authorization headerWCF REST 基本身份验证 - 无法设置授权标头
【发布时间】:2014-02-10 20:09:20
【问题描述】:

我已经创建了一个 WCF REST 服务,并且我正在尝试进行自定义身份验证(因为它应该适用于 http 和 https)。

我正在使用客户服务授权管理器来检查和验证授权标头。

当我使用 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>

我正在使用客户服务授权管理器来检查和验证授权标头。

【问题讨论】:

    标签: c# wcf rest wcf-rest


    【解决方案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()
      

    【讨论】:

      【解决方案2】:

      为了后代,这是我找到的解决这个问题的方法:

      首先,在您的客户端中取出您的&lt;service&gt;&lt;/service&gt; 标签。

      然后,您需要将对服务的调用包装在 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-30
        • 2015-05-05
        • 2012-10-02
        • 1970-01-01
        • 2013-05-18
        • 1970-01-01
        • 1970-01-01
        • 2013-05-31
        相关资源
        最近更新 更多