web-dev-qa-db-fra.com

WCF sur SSL - erreur 404

D'accord, je dois manquer quelque chose de très simple ici, parce que je google depuis des jours, et que je regarde des dizaines de réponses là-bas, et ici sur SO, et je ne peux PAS faire en sorte que cela fonctionne, peu importe ce que j'ai essayé. Le service fonctionne parfaitement bien lorsqu'il est appelé via HTTP simple.

Voici notre configuration ... nous avons un domaine, http://www.mydomain.com . Nous avons un certificat SSL installé sur ce domaine de thawte, tout comme nous le ferions si nous sécurisions un site de commerce électronique. Tout fonctionne bien, et je peux aller sur http s : //www.mydomain.com et cela fonctionne correctement. J'exécute VS2008, le site .NET 3.5 sur Windows Server 2003 R2.

Maintenant, j'ai ajouté un service WCF compatible Silverlight à mon site, avec lequel je souhaite communiquer via SSL. Si je navigue vers http s : //www.mydomain.com/myservice.svc, cela me montre le descriptif WSDL " Vous avez créé une page de service "comme prévu, qui montre comment créer votre client en utilisant

svcutil.exe https:// ... 

EDIT: J'ai réalisé que l'URL affichée pour le svcutil dans le fichier wsdl pointait en fait vers le nom de la boîte physique du serveur Web, pas le domaine approprié. J'ai donc suivi les étapes indiquées dans cet article de blog pour mettre à jour la liaison sécurisée du site Web en IIS en utilisant le script adsutil. Maintenant, le fichier wsdl affiche la bonne adresse SSL, mais j'obtiens toujours la même erreur.

Maintenant, je suis allé et j'ai essayé d'y connecter mon application Silverlight, et cela ne fonctionne pas, renvoyant une exception dans le résultat des appels asynchrones, indiquant " Le serveur distant a renvoyé une erreur: NotFound . Un certain nombre de blogs que j'ai lus ont parlé de le réduire aux problèmes de Silverlight en créant une application Windows de test et en essayant de la référencer à partir de cela. Eh bien, je l'ai fait et même dans une application Windows standard essayant d'accéder au service via SSL, j'obtiens une exception indiquant:

System.ServiceModel.EndpointNotFoundException: 
There was no endpoint listening at https://www.mydomain.com/mysubdir/myservice.svc that could accept the message. 
This is often caused by an incorrect address or SOAP action. 
See InnerException, if present, for more details. ---> 
System.Net.WebException: The remote server returned an error: (404) Not Found.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

Ceci malgré le fait que j'ai explicitement ajouté la référence de service à l'application Windows en utilisant le schéma HTTPS et qu'il récupère correctement toutes les méthodes et les affiche dans Intellisense dans l'éditeur.

Notez qu'il s'agit d'un service qui ne nécessite PAS de connexion explicite de la part de l'utilisateur. Je vais envoyer des en-têtes personnalisés dans mes enveloppes SOAP pour vérifier que les demandes proviennent de notre application, et je veux juste empêcher les prédateurs de flairer la ligne et de choisir les en-têtes personnalisés.

Passons maintenant au code, où je dois juste avoir un mauvais réglage stupide, car d'après tout ce que j'ai lu, cela devrait être un exercice assez simple.

Tout d'abord, la classe code-behind de mon service est décorée avec les attributs suivants:

<ServiceBehavior(AddressFilterMode:=AddressFilterMode.Any)> 
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)>

La section ServiceModel de mon web.config sur le serveur ressemble à ceci:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="basicHttpBinding">
                <security mode="Transport">
                    <transport clientCredentialType ="None"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="standingsBehavior">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                    <serviceDebug includeExceptionDetailInFaults="false"/>
                </behavior>
            </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
        <baseAddressPrefixFilters>
            <add prefix="http://www.mydomain.com:80"/>
        </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <services>
        <service behaviorConfiguration="standingsBehavior" name="lijslwebdata">
            <endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/>
            <!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>-->
        </service>
    </services>
</system.serviceModel>

Et la section ServiceModel de app.config dans mon application Windows ressemble à ceci:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_lijslwebdata" 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://www.mydomain.com/mysubdir/myservice.svc"
            binding="basicHttpBinding" 
            bindingConfiguration="BasicHttpBinding_lijslwebdata"
            contract="xdata.lijslwebdata" name="BasicHttpBinding_lijslwebdata" />
    </client>
</system.serviceModel>
39
eidylon

D'accord, j'ai apparemment résolu le problème, et je n'ai absolument aucune idée pourquoi/comment.

Voici ce que j'ai fait.

  • J'ai ajouté un service WCF BRAND NEW EMPTY compatible Silverlight
  • J'ai ensuite mis à jour le web.config pour refléter les deux services
  • J'ai ensuite littéralement simplement copié et collé tout ce qui concerne le premier service dans le deuxième service, sauf le nom.

Pourquoi cela l'a-t-il corrigé, je n'en ai absolument aucune idée.

FWIW pour tout le monde, voici ma nouvelle section web.config ServiceModel avec le deuxième service dedans ...

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="basicHttpBinding">
            </binding>
            <binding name="basicHttpsBinding">
                <security mode="Transport">
                    <transport clientCredentialType ="None"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="standingsBehavior">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
        <baseAddressPrefixFilters>
            <add prefix="http://www.mydomain.com/"/>
        </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <services>
        <service behaviorConfiguration="standingsBehavior" name="lijslwebdata">
            <endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
        <service behaviorConfiguration="standingsBehavior" name="sslwebdata">
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="sslwebdata"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
</system.serviceModel>
1
eidylon

J'ai eu ce même problème de mon côté. Votre message m'a aidé à comprendre quel était le problème. voici ma section modèle de service. J'ai découvert que les clés étaient le httpsGetEnabled puis en définissant le bindingconfiguration J'espère que cela aide.

<system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="RequestImageBehavior">
                    <serviceMetadata **httpsGetEnabled**="true" />
                    <serviceDebug includeExceptionDetailInFaults="false" />
                  <dataContractSerializer maxItemsInObjectGraph="1073741824" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <services>
            <service behaviorConfiguration="RequestImageBehavior" name="RequestImage">
                <endpoint address="" 
                          binding="wsHttpBinding" 
                          **bindingConfiguration**="HttpsBinding"
                          contract="IRequestImage">
                </endpoint>
                <endpoint address="mex" 
                          binding="mexHttpBinding" 
                          contract="IMetadataExchange" />
            </service>
        </services>
      <bindings>
        **<wsHttpBinding>
          <binding name="HttpsBinding">
            <security mode="Transport">
              <transport clientCredentialType="None"/>
            </security>
          </binding>
        </wsHttpBinding>**
      </bindings>
    </system.serviceModel>
27
user209884

J'avais affaire à cela récemment et je veux ajouter un Tweak. Si vous suivez les instructions ci-dessus, vous pourrez faire fonctionner le service avec HTTPS, mais pas simultanément sur HTTP et HTTPS. Pour ce faire, vous devez disposer de deux nœuds de configuration de point de terminaison, un pour chaque protocole, comme suit:

 <service name="MyCompany.MyService" >
    <endpoint address="" behaviorConfiguration="AspNetAjaxBehavior"
      binding="webHttpBinding" contract="MyCompany.MyService" bindingConfiguration="sslBinding" />
    <endpoint address="" behaviorConfiguration="AspNetAjaxBehavior"
      binding="webHttpBinding" contract="MyCompany.MyService" />
  </service>

(extrait de ma base de code, ajustez la configuration de comportement et la liaison selon le cas)

11
John Ketchpaw

Je viens de passer quelques heures là-dessus et il s'est avéré que mon problème était le nom du service

<services>
      <service name="TimberMill.Web.Data.LogReceiverService">
        <endpoint binding="basicHttpBinding" bindingConfiguration="basicBinding"
                     contract="NLog.LogReceiverService.ILogReceiverServer" />
      </service>
    </services>

devait correspondre exactement à l'entrée similaire dans mon fichier * .svc.

<%@ ServiceHost 
    Language="C#" 
    Debug="true" 
    Service="TimberMill.Web.Data.LogReceiverService, TimberMill.Web"
    Factory="Autofac.Integration.Wcf.AutofacServiceHostFactory, Autofac.Integration.Wcf"
    CodeBehind="LogReceiverService.svc.cs" 
%>

Je ne sais pas si cela était lié à mon utilisation d'Autofac. Tout fonctionnait bien sous HTTP simple. Échec sous HTTPS cependant.

Eh bien, je pense que oui, je ne veux rien déranger maintenant en testant plus en détail de peur que je ne fâche les dieux WCF-Config et que ma configuration ne se brise à nouveau. YMMV.

8
fiat

Dans mon cas, aucune de ces réponses n'a aidé.

Au lieu de cela, je devais ajouter un doublon <binding> section qui n'a pas d'attribut name .

Voici le vidage de la section appropriée du fichier web.config de mon service:

<behaviors>
    <serviceBehaviors>
        <behavior name="ServiceBehaviour">
            <serviceMetadata 
                httpsGetEnabled="true" 
                httpsGetUrl="RemoteSyncService.svc"
                httpGetBindingConfiguration="bindingConfig" />
            <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
        <behavior name="">
            <serviceMetadata 
                httpsGetEnabled="true" 
                httpsGetUrl="RemoteSyncService.svc" />
            <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
    </serviceBehaviors>
</behaviors>

<bindings>
  <basicHttpBinding>
    <binding name="bindingConfig" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed">
        <security mode="Transport">
          <transport clientCredentialType="None"/>
        </security>
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
    </binding>

    <!-- Add binding with EMPTY/MISSING name, see https://forums.iis.net/t/1178173.aspx -->
    <binding maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" transferMode="Streamed">
        <security mode="Transport">
          <transport clientCredentialType="None"/>
        </security>
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
    </binding>
  </basicHttpBinding>
</bindings>

J'espère que cela pourrait être utile à quelqu'un, un jour.

3
Uwe Keim

J'ai eu le même problème et j'ai passé une journée à résoudre ce problème. Enfin, la configuration ci-dessous m'a fonctionné pour l'accès HTTPS.

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="basicHttpBinding">
            </binding>
            <binding name="basicHttpsBinding">
                <security mode="Transport">
                    <transport clientCredentialType ="None"/>
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="standingsBehavior">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
        <baseAddressPrefixFilters>
            <add prefix="http://www.mydomain.com/"/>
        </baseAddressPrefixFilters>
    </serviceHostingEnvironment>
    <services>
        <service behaviorConfiguration="standingsBehavior" name="lijslwebdata">
            <endpoint address="" binding="basicHttpBinding" contract="lijslwebdata"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
        <service behaviorConfiguration="standingsBehavior" name="sslwebdata">
            <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="sslwebdata"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
</system.serviceModel>
2
Murali

Plusieurs des réponses m'ont amené à reconfigurer mon web.config pour contenir deux points de terminaison. Je me suis retrouvé avec ce Web.config suivant.

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpBinding">
        </binding>
        <binding name="basicHttpsBinding">
          <security mode="Transport">
            <transport clientCredentialType ="None"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="standingsBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
      <baseAddressPrefixFilters>
        <add prefix="http://www.myhost.com"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>

    <services>
      <service behaviorConfiguration="standingsBehavior" name="NameSpace.ClassName">
        <endpoint address="" binding="basicHttpBinding" contract="NameSpace.ContractInterfaceName"/>
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="NameSpace.ContractInterfaceName"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
  </system.serviceModel>
1
Harald Lund

Cela ne fonctionnait pas pour vous auparavant, car vous avez nommé votre basicHttpBinding configuration basicHttpBinding mais n'avez pas référencé cette configuration dans votre <service> tag avec le bindingConfiguration="basicHttpBinding"

Dans vos modifications qui ont fonctionné en ajoutant une autre configuration de service, vous avez ensuite référencé la configuration de liaison qui contient le <security> node provoquant ainsi son fonctionnement.

1
Huzaifa Tapal

Tout semble être tout à fait valable, aucune erreur flagrante du tout ...

Juste une observation/question: où se trouve votre fichier * .svc ??

Dans le message d'erreur, je vois:

 https://www.mydomain.com/myservice.svc 

Votre fichier * .svc se trouve-t-il vraiment dans le répertoire virtuel de niveau supérieur de votre site?

En règle générale, le fichier * .svc se trouve dans un répertoire virtuel sur IIS et donc l'adresse serait quelque chose comme:

 https://www.mydomain.com/YourVirtualDirectory/myservice.svc 

Bien sûr, vous pouvez déployer une application ASP.NET et un fichier de service WCF * .svc à la racine de votre IIS - mais ce n'est pas très courant, selon mon expérience.

Juste un truc à vérifier .....

Marc

1
marc_s

Juste une autre chose pour vérifier si vous rencontrez la même erreur 404 que OP. J'ai tripoté beaucoup de choses, mais finalement la solution s'est résumée à simplement ajouter l'espace de noms à mon service web.config.

Donc, les anciens ServiceFoo et IServiceFoo ne fonctionnaient PAS:

  <services>
     <service behaviorConfiguration="quuxBehavior" name="ServiceFoo">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="IServiceFoo"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
     </service>
  </services>

Mais l'ajout de l'espace de noms (ProjectBar) DID fonctionne:

  <services>
     <service behaviorConfiguration="quuxBehavior" name="ProjectBar.ServiceFoo">
        <endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpsBinding" contract="ProjectBar.IServiceFoo"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
     </service>
  </services>
0
Matthew Lowe