J'ai passé beaucoup de temps à comprendre comment configurer mes services WCF afin qu'ils fonctionnent pour https dans l'environnement de production.
En gros, je devais faire ceci:
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
<service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
<endpoint address="" bindingNamespace="https://secure.mydomain.com" binding="basicHttpBinding" bindingConfiguration="HttpsBinding" contract="MyNamespace.IMyService"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="HttpsBinding">
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
L'ajout de l'attribut bindingNamespace
au système d'extrémité est la dernière chose qui a permis de le faire fonctionner.
Mais cette configuration ne fonctionne pas dans mon environnement de développement local où je travaille sous http. Donc ma config il y a:
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
<service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="MyNamespace.IMyService"/>
</service>
</services>
Les différences ici sont que j'ai défini l'attribut httpsGetEnabled
sur false et que j'ai supprimé le bindingConfiguration et le bindingNamespace.
Le problème est le suivant: comment créer un bloc de configuration qui gère les DEUX?
Je déteste vraiment avoir à faire beaucoup de modifications spéciales à la configuration chaque fois que je fais une release. Oui, je sais que je pourrais avoir une tâche post-build qui modifie automatiquement les valeurs, mais j'aimerais fusionner les configs si possible.
J'ai essayé quelque chose comme ça:
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
<service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="MyNamespace.IMyService"/>
<endpoint address="" bindingNamespace="https://secure.mydomain.com" binding="basicHttpBinding" bindingConfiguration="HttpsBinding" contract="MyNamespace.IMyService"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="HttpsBinding">
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
J'ai pensé que mettre les deux points de terminaison lui donnerait deux options à rechercher lors de l'activation du service. Cependant, cela ne fonctionne pas. Je reçois cette erreur:
Impossible de trouver une adresse de base correspondant au schéma https du système d'extrémité avec la liaison BasicHttpBinding. Les schémas d'adresses de base enregistrés sont [http].
En regardant autour de SO et du reste de l'Internet, il apparaît que d'autres ont eu des problèmes pour tuer ce dragon.
Un problème avec votre configuration combinée est que vos deux ordinateurs d'extrémité se trouvent sur la même adresse - cela ne fonctionnera pas.
Si vous hébergez chez IIS, votre serveur, votre répertoire virtuel et le fichier * .svc nécessaire détermineront votre adresse de base.
http://yourservername/VirtualDirectory/YourService.svc
Si vous souhaitez avoir deux points de terminaison, au moins l'un d'entre eux doit définir une adresse relative:
<services>
<service name="MyNamespace.MyService"
behaviorConfiguration="MyServiceBehavior">
<endpoint
address="basic"
binding="basicHttpBinding"
contract="MyNamespace.IMyService"/>
<endpoint
address="secure"
binding="basicHttpBinding" bindingConfiguration="HttpsBinding"
contract="MyNamespace.IMyService"/>
</service>
</services>
Dans ce cas, vous auriez votre noeud final HTTP sur:
http://yourservername/VirtualDirectory/YourService.svc/basic
et votre point de terminaison HTTPS sécurisé sur:
https://yourservername/VirtualDirectory/YourService.svc/secure
De plus, votre point de terminaison sécurisé utilise une configuration HttpsBinding
- mais il vous manque une telle configuration de liaison - vous n'avez que:
<bindings>
<basicHttpBinding>
<binding name="HttpBinding">
<security mode="None">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
Vous devez ajouter la configuration HttpsBinding
!!
<bindings>
<basicHttpBinding>
<binding name="HttpBinding">
<security mode="None">
<transport clientCredentialType="None"></transport>
</security>
</binding>
<binding name="HttpsBinding">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
Le problème ne vient pas du fichier de configuration, mais de la configuration IIS. Vous devez activer HTTP et HTTPS dans IIS. Dans IIS 7.5 , accédez à votre site et cliquez sur Liaisons sous Modifier une action du site. Assurez-vous que http & https ont été ajoutés. Vous devez ensuite créer une liaison pour HTTP sous <basicHttpBinding>
, avec le mode de sécurité défini sur none. Ajoutez la configuration de liaison nouvellement créée au point de terminaison http. .____.]Tu es prêt. Faites-moi savoir si vous avez besoin d'autre numéro.
La solution pour une exécution dans un domaine local et également pour une utilisation dans des environnements de production et autres, sans dépendre de la mémoire pour changer quoi que ce soit, consiste en des transformations de configuration. Ils transforment le fichier Web.config compilé en fonction du profil de configuration sélectionné. Localement, je cours en mode Debug
, dans l’environnement de test I publish vers un profil TestRelease
et en production j’ai un autre profil:
Si vous ne pouvez pas développer votre web.config, vous pouvez cliquer avec le bouton droit de la souris et ajouter des fichiers de configuration. Afin d'obtenir plus que Debug et Release, vous ajoutez plus de configurations via le gestionnaire:
Voici des exemples de transformations:
<configuration xmlns:xdt="http://schemas.Microsoft.com/XML-Document-Transform">
<!--...-->
<system.serviceModel>
<protocolMapping>
<add binding="basicHttpBinding" scheme="http" xdt:Transform="SetAttributes" />
</protocolMapping>
<bindings>
<basicHttpBinding>
<binding xdt:Locator="Match(name)" name="basicHttpBindingConfiguration">
<security xdt:Transform="Remove">
<transport xdt:Transform="Remove"/>
</security>
</binding>
<binding xdt:Locator="Match(name)" name="fileTransferBinding">
<security xdt:Transform="Remove">
<transport xdt:Transform="Remove"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
<configuration xmlns:xdt="http://schemas.Microsoft.com/XML-Document-Transform">
<!--...-->
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" xdt:Transform="Replace"/>
<serviceDebug includeExceptionDetailInFaults="false" xdt:Transform="Replace"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" xdt:Transform="Replace"/>
</protocolMapping>
<bindings>
<basicHttpBinding>
<binding xdt:Locator="Match(name)" name="basicHttpBindingConfiguration">
<security mode="Transport" xdt:Transform="Insert">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
<binding xdt:Locator="Match(name)" name="fileTransferBinding">
<security mode="Transport" xdt:Transform="Insert">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled="false" xdt:Transform="Replace"/>
</system.webServer>
</configuration>