2009-04-30 7 views
19

J'ai créé une procuration d'un service Web avec Visual Studio 2008, et il a créé pour moi l'entrée suivante dans le app.config:Se connecter avec WCF à un WebService authentifié avec nom d'utilisateur/mot de passe

<system.serviceModel> 
     <bindings> 
      <basicHttpBinding> 
       <binding name="MyNameHandlerSoapBinding" 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="None"> 
         <transport clientCredentialType="None" proxyCredentialType="None" 
          realm="" /> 
         <message clientCredentialType="UserName" algorithmSuite="Default" /> 
        </security> 
       </binding> 
      </basicHttpBinding> 
     </bindings> 
     <client> 
      <endpoint address="http://www.***/***/***" 
       binding="basicHttpBinding" bindingConfiguration="MyNameHandlerSoapBinding" 
       contract="***.MyNameHandler" name="MyName"> 
      </endpoint> 
     </client> 
    </system.serviceModel> 

webservice est l'authentification par nom d'utilisateur/mot de passe, je dois donc l'ajouter quelque part ici. Je suis un peu perdu dans la mer de la documentation WCF, je pense que je dois changer de basicHttpBinding à wsHttpBinding ou customBinding pour pouvoir ajouter les éléments d'authentification, mais je ne le comprends pas vraiment. Quelqu'un pourrait-il donner un conseil rapide ou un lien utile qui dit comment le faire?

EDIT:

J'ai changé la section de sécurité:

<security mode="Transport"> 
    <transport clientCredentialType="Basic" proxyCredentialType="None" 
     realm="" /> 
</security> 

et ajouté dans le code:

ws.ClientCredentials.UserName.UserName = ""; 
ws.ClientCredentials.UserName.Password = ""; 

Maintenant, il semble qu'il utilise peut-être les pouvoirs, mais il est me donner l'erreur:

l'URI fourni système « http » est URI non valide devrait « https »

Je ne sais même pas si cela est la bonne façon de procéder ...

+3

WCF est la configuration d'enfer. Quel magasin d'auth que voulez-vous utiliser? Windows ... adhésion ASP ou personnalisé comme une base de données? Et avez-vous regardé à travers cela: http://msdn.microsoft.com/en-us/library/bb398990.aspx –

+0

En effet. C'est un service Web externe qui a un nom d'utilisateur/mot de passe unique à utiliser pour tous mes appels. Et c'est http. Donc, je suppose que cela pourrait être plus d'une autorisation de point de terminaison, si cela a du sens! – antonioh

+0

Il est d'abord question que vous ne pouvez pas spécifier le nom d'utilisateur et mot de passe n'importe où dans la configuration (mais seulement dans le code) - encore une fois, voulez-vous avoir votre mot de passe dans un fichier de configuration en texte clair? VRAIMENT? –

Répondre

34

je poste ici la solution pour les futurs lecteurs:

<system.serviceModel> 
    <bindings> 
     <basicHttpBinding> 
     <binding name="MyHandlerSoapBinding" 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="TransportCredentialOnly"> 
      <transport clientCredentialType="Basic" /> 
      </security> 
     </binding> 
     </basicHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://www.***/***/***/MyHandler" 
      binding="basicHttpBinding" bindingConfiguration="MyHandlerSoapBinding" 
      contract="***.MyHandler" name="MyHandler"> 
     </endpoint> 

    </client> 
    </system.serviceModel> 

En fin de compte que je pouvais utiliser le basicHttpBinding par défaut. La seule différence avec le code affiché dans la question est le nœud de sécurité.

Notez également le mode = "TransportCredentialOnly option", ce qui vous permet d'envoyer le nom d'utilisateur/mot de passe à l'aide http au lieu de https. Ceci est nécessaire pour tester les environnements comme celui que j'utilise. Plus tard, évidemment, vous préférerez https pour envoyer vos informations d'identification.

Ensuite dans le code que vous entrez votre nom d'utilisateur/mot de passe:

var ws = new ***.MyHandlerClient("MyHandler"); 
ws.ClientCredentials.UserName.UserName = "myUsername"; 
ws.ClientCredentials.UserName.Password = "myPassword"; 
var result = ws.executeMyMethod(); 
+0

Cela a vraiment fait ma journée! Merci beaucoup pour le partage, cela a sauvé beaucoup de gens beaucoup d'ennuis. – cudahead

+0

@antonioh J'ai 'La requête HTTP a été interdite avec le schéma d'authentification client 'Basic'.' avec cette approche; Savez-vous ce qui pourrait causer cela? – FMFF

+0

Argh ... qui aurait trouvé le ... UserName.UserName .... –

5

Le message d'erreur est juste. WCF ne permet pas le transport de noms d'utilisateur et de mots de passe sur un protocole non protégé. Une fois que vous avez un certificat SSL, vous disposez de deux options pour l'envoi des informations d'identification, le transport ou la sécurité et plusieurs options pour le type de données d'identification. MSDN a un good guide à toutes les différentes options.

+1

Trouvé. Cela vous permet avec l'option . Bien sûr, ceci est pour un environnement de test, plus tard, vous devriez utiliser https. Bravo – antonioh

1

J'ai eu le même problème et a essayé la solution ci-dessus D'une certaine façon cela ne fonctionne pas pour moi j'étais continue à recevoir le message " Aucun en-tête WS-Security trouvé "

Après une longue période de tests et d'essais, je parviens à le faire fonctionner J'ai ajouté le code d'en-tête dans le client comme ci-dessous et puis ça marche!

<client> 
    <endpoint address="http://your.service.com" binding="basicHttpBinding" bindingConfiguration="XXXBinding" contract="contract.XXX" name="XXXPort"> 
     <headers xmlns:wsse="http://your.xsd"> 
      <wsse:Security mustUnderstand="1"> 
       <wsse:UsernameToken> 
        <tenant>XXX</tenant> 
        <wsse:Username>XXX</wsse:Username> 
        <wsse:Password Type="http://www.xxxx.com/wss#PasswordText">XXX</wsse:Password> 
       </wsse:UsernameToken> 
      </wsse:Security> 
     </headers> 
    </endpoint> 
</client> 
Questions connexes