2013-04-30 25 views
7

Sto tentando di utilizzare un servizio Web di terzi che è protetto con un utente/pass. Credo di aver fatto ciò che è necessario per autenticare e impostare l'utente e passare, ma sembra non includerli nell'intestazione http o qualcosa del genere ...WCF - BasicHttpBinding, non sono disponibili nome utente e/o password, nome: null, password: null

Quando si tenta di chiamare;

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

Ottengo questo errore;

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

codice completo:

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> 

+1

Ebbene, al fine di eliminare un certo potenziale confusione, la tua seconda definizione vincolante ('ServiceSoapBinding1') non è attualmente riferimento (nel codice che avete dimostrato), quindi sarà ignorata e si potrebbe tranquillamente rimuoverlo. – paul

+1

Grazie, l'ho mancato durante la pubblicazione. Rimosso dall'esempio. – Tomcat

+1

Domanda stupida, ma hai qualche documentazione su come fare questo? Cosa dice la terza parte? –

risposta

5

Dopo un sacco di problemi, ho scoperto che per qualche motivo l'intestazione di autorizzazione non veniva inviato al servizio. Per includerlo dovevo fare il seguente per la chiamata al servizio. Ciò di cui sono ancora confuso è perché questo è un problema. Da quello che pensavo che BasicHttpBinding avrebbe dovuto includere le credenziali nell'intestazione per impostazione predefinita? Qualsiasi intuizione di qualcuno sul motivo per cui questo è stato un problema per me sarebbe molto apprezzato. E una buona risposta potrebbe comunque ottenere il +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 
1

Se l'autenticazione richiesto è solo HTTP di base, allora è necessario specificare la sicurezza del basicHttpBinding come segue :

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

si può ovviamente scegliere di specificare questi in codice invece.

Le credenziali reali devono essere sempre espressi in codice:

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

Il servizio utilizza Basic, ma se utilizzo transportCredentialOnly non mi piace l'URL https. Inoltre, se faccio quello che sto facendo nel codice, quel binding app.config è usato anche per qualcosa? – Tomcat

Problemi correlati