【问题标题】:WCF - BasicHttpBinding, No user name and/or password is available, name: null, password: nullWCF - BasicHttpBinding,没有可用的用户名和/或密码,名称:null,密码:null
【发布时间】:2013-04-24 14:42:33
【问题描述】:

我正在尝试使用受用户/通行证保护的第三方网络服务。我相信我已经完成了对用户进行身份验证和设置并通过所需的操作,但它似乎没有将它们包含在 http 标头或其他东西中......

尝试调用时;

nameList.AddRange(service.getBlobNameByIdAndSectionId(section, id))

我收到此错误;

No user name and/or password is available, name: null, password: null

完整代码:

Private Function GetVendorService() As Services.ServiceClient
    Dim binding As New BasicHttpBinding(BasicHttpSecurityMode.Transport)

    binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic
    Dim ea As New EndpointAddress(GetVendorServiceURL())

    Dim service As New Services.ServiceClient(binding, ea)
    service.ClientCredentials.UserName.UserName = "user"
    service.ClientCredentials.UserName.Password = "password"

    Return service

End Function

Public Function GetVendorServiceURL() As String
    Select Case Informix.HostType
        Case HostServerType.Stage
            Return "https://url-s.net:8443/cxf/Service/v1/ws"
        Case HostServerType.Dev
            Return "https://url-d.net:8443/cxf/Service/v1/ws"
        Case Else 'Live
            Return "https://url.net:8443/cxf/Service/v1/ws"
    End Select
End Function

Private Function GetPdfListById(ByVal Id As Integer, ByVal Section As SectionId) As List(Of Services.blobName)
    Dim service As Services.ServiceClient = GetVendorService()
    Dim nameList As New List(Of Services.blobName)
    service.Open()
    nameList.AddRange(service.getBlobNameByIdAndSectionId(section, id))
    service.Close()
    Return nameList
End Function

app.config

<system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="ServiceSoapBinding" closeTimeout="00:01:00"
      openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
      allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
      maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
      messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
      useDefaultWebProxy="true">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <security mode="Transport">
        <transport clientCredentialType="None" proxyCredentialType="None"
          realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="https://url.net:8443/cxf/Service/v1/ws"
    binding="basicHttpBinding" bindingConfiguration="ServiceSoapBinding"
    contract="Services.Service"
    name="ServiceSoapPort" />
</client>

【问题讨论】:

  • 好吧,为了消除一些潜在的混淆,您的第二个绑定定义 (ServiceSoapBinding1) 当前未引用(在您显示的代码中),因此将被忽略,您可以安全地删除它.
  • 谢谢,发帖时错过了。从示例中删除它。
  • 愚蠢的问题,但是你有关于如何做到这一点的任何文档吗?第三方怎么说?
  • @hugh - 仅在线找到用于在 WCF 中发送基本身份验证安全性的文档,在此之前我个人从未使用过 WCF。当看到我们遇到问题时,第三方向我们发送了 msdn 代码的链接......他们使用基本身份验证并正在使用 ServiceMix,这是我对他们的最终了解的程度。我正在使用 BasicHttpBinding 因为他们使用 Soap1.1 而不是 1.2,所以 WsHttpBinding 不喜欢这样,使用在代码中创建的自定义绑定来使用 Soap1.1 会出现 MustUnderstandHeaders 错误,我不确定这是否是一个进步或向后。
  • 此外,使用 BasicHttpSecurityMode.TransportWithMessageCredential 会给我一个 MustUnderstand 标头错误。

标签: vb.net wcf web-services


【解决方案1】:

经过很多问题后,我发现由于某种原因未将 Authorization 标头发送到服务。为了包含它,我必须执行以下操作来调用服务。我仍然困惑的是为什么这是一个问题。从我认为 BasicHttpBinding 默认情况下应该在标头中包含凭据?任何人对为什么这对我来说是一个问题的任何见解将不胜感激。一个好的答案可能仍然会得到 +50。

Private Function GetPdfListById(ByVal Id As Integer, ByVal Section As SectionId) As List(Of VendorGuideService.vogBlobName)
    Using service As Service.ServiceClient = GetVendorService()
        Dim nameList As New List(Of Service.blobName)
        Using scope As ServiceModel.OperationContextScope = New ServiceModel.OperationContextScope(service.InnerChannel)
            Dim request As New ServiceModel.Channels.HttpRequestMessageProperty()
            request.Headers.Add("Authorization", "Basic " & Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes(service.ClientCredentials.UserName.UserName & ":" & _
                                                                                                    service.ClientCredentials.UserName.Password)))
            ServiceModel.OperationContext.Current.OutgoingMessageProperties(ServiceModel.Channels.HttpRequestMessageProperty.Name) = request
            nameList.AddRange(service.getBlobNameByIdAndSectionId(section, id))
        End Using
        Return nameList
    End Using
End Function

【讨论】:

    【解决方案2】:

    如果需要的认证只是HTTP Basic,那么你需要指定basicHttpBinding的安全性如下:

    <basicHttpBinding>
        <binding ...>
            <security mode="TransportCredentialOnly">
                <transport clientCredentialType="Basic" />
            </security>
        </binding>
    </basicHttpBinding>
    

    您当然可以选择在代码中指定这些。

    实际的凭据必须始终在代码中给出:

    client.ClientCredentials.UserName.UserName = "userName";
    client.ClientCredentials.UserName.Password = "password";
    

    【讨论】:

    • 该服务使用 Basic,但如果我使用 transportCredentialOnly,它不喜欢 https url。另外,如果我在代码中执行我正在执行的操作,那么 app.config 绑定是否会用于任何用途?
    猜你喜欢
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多