web-dev-qa-db-fra.com

Comment puis-je combiner la configuration des services WCF pour http et https dans un seul fichier web.config?

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.

23
sohtimsso1970

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>
14
marc_s

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.

2
mohit bansal

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:

 Web.Config Transforms in Visual Studio

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:

 Configuration Manager in Visual Studio

Voici des exemples de transformations:

Web.Debug.config

<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>

Web.Release.config

<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>
0
Aske B.