web-dev-qa-db-fra.com

Configurer IIS Express 8 pour activer CORS

J'écris des services WCF qui seront utilisés par les clients dans la nature, ils doivent donc traiter les demandes provenant de plusieurs pays. Je ne parviens pas à autoriser mon serveur de développement à accepter de telles demandes. Voici le scénario:

  • J'exécute le projet WCF dans une instance de Visual Studio 2012, en utilisant IIS Express 8 en tant que serveur sur un port spécifique.
  • J'exécute le projet client dans une autre instance de Visual Studio 2012, en utilisant également IIS Express 8 en tant que serveur. Ce projet utilise AJAX pour utiliser les services de l'autre projet.

Lorsque j'exécute le projet client dans IE, il n'y a pas de problème, car IE n'envoie pas la demande de contrôle en amont OPTIONS. Cependant, lorsque je l'exécute dans Chrome, la requête OPTIONS de preflight renvoie une méthode 405 non autorisée et Chrome renonce au service. Les versions précédentes de Chrome ignoraient simplement l'erreur et continuaient avec la demande POST réelle (ou Get, peu importe ...), mais les versions ultérieures semblaient plus difficiles.

J'ai également rencontré ce problème avec un projet WCF déployé et je l'ai résolu en déplaçant OPTIONSVerbHandler en haut de la liste Mappages de gestionnaires dans IIS.

Je dois préciser que j'utilise les paramètres web.config les plus généreux auxquels je puisse penser pour essayer d'autoriser la CORS. Par exemple, j'ai ceci dans la configuration du projet WCF:

<httpProtocol>
  <customHeaders>
    <remove name="X-Powered-By" />
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="*" />
    <add name="Access-Control-Allow-Methods" value="*" />
    <add name="X-Powered-By" value="*" />
  </customHeaders>
</httpProtocol>

Quoi qu'il en soit, toutes les demandes de clients d'origine croisée adressées au projet WCF exécuté à partir de code échouent avec l'erreur 405.

Toute aide pour configurer le projet WCF lui-même ou IIS Express 8 pour activer CORS?

Merci!

9
djo.dadof2

La réponse est que la configuration nécessaire pour permettre à WCF d'accepter les messages de contrôle en amont de CORS n'a rien à voir avec le serveur IIS; le projet WCF lui-même doit plutôt être configuré pour gérer la requête HTTP avec le verbe OPTIONS.

Longue histoire courte: faire ceci est VRAIMENT DUR. WCF est un touche-à-tout en matière de points de terminaison; il est donc déconseillé de le configurer pour faire quelque chose de très spécifique avec l'un (HTTP), bien que cela puisse être fait. La vraie solution consiste à utiliser Web API, qui est un maître de HTTP et peut être configuré pour effectuer CORS très simplement.

1
djo.dadof2

Vous pouvez activer cors pour wcf, et cela peut être assez simple, une fois que vous savez comment faire.

En partant de la réponse de David G sur la question plus générale "cors sur IIS" , réponse qui est vraiment proche de ce qui est requis pour une solution de base:

  • Commencez par configurer la variable OPTIONSVerbHandler pour qu'elle s'exécute avant les gestionnaires .Net.

    1. Dans la console IIS, sélectionnez "Mappages de gestionnaires". (Faites cela au niveau du serveur ou du site. Au niveau du site, il redéfinira tous les gestionnaires pour votre site et ignorera toute modification apportée au niveau du serveur par la suite. Et bien sûr, au niveau du serveur, cela pourrait endommager d'autres sites propre gestion des options verbe.) 
    2. Dans le volet Actions, sélectionnez "Afficher la liste ordonnée ...". Cherchez OPTIONSVerbHandler et déplacez-le vers le haut (beaucoup de clics ...).

    Vous pouvez également le faire dans web.config en redéfinissant tous les gestionnaires sous <system.webServer><handlers>. (<clear> puis <add ...> retour, c’est ce que fait la console IIS pour vous. En passant, il n’est pas nécessaire de demander l’autorisation de "lecture" sur ce gestionnaire.)

  • Deuxièmement, configurez des en-têtes http personnalisés pour vos besoins cors, tels que:

    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Origin" value="*"/>
          <add name="Access-Control-Allow-Headers" value="Content-Type"/>
          <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS"/>
        </customHeaders>
      </httpProtocol>
    </system.webServer>
    

    Cet exemple les définit pour toutes les réponses à toutes les demandes sur le site/app/répertoire dans lequel se trouve web.config. Si vous voulez les restreindre à une URL, mettez-la dans une balise <location>.
    Vous pouvez également ajouter ces en-têtes personnalisés dans la console IIS. 

Il s’agit d’une solution de base car elle enverra des en-têtes CORS même sur demande qui ne le nécessite pas, ouvrant peut-être votre application à des utilisations inattendues. Mais avec WCF, cela semble être le plus simple.

Avec MVC ou webapi, nous pourrions plutôt gérer le verbe OPTIONS et corser les en-têtes par code ("manuellement" ou avec le support intégré disponible dans la dernière version de webapi).

13
Frédéric
  • en tant que valeur n'est valide que pour Access-Control-Allow-Origin. Pour les autres, vous devez être explicite. Par exemple:

Méthodes d'accès-contrôle-autoriser: GET, PUT, POST, DELETE

ou bien:

Méthodes d'accès au contrôle d'accès: PUT, DELETE

parce que la spécification dit que GET et POST sont impliqués.

3
Brock Allen

Je voulais simplement mentionner que, au moment de la rédaction de ce document, je ne pense pas que les navigateurs Web prennent en charge la valeur générique * pour Access-Control-Allow-Methods ou Access-Control-Allow-Headers, même si elle est conforme aux spécifications.

Spec:

https://www.w3.org/TR/cors/
https://tools.ietf.org/html/rfc2616#section-4.2

Voir Notes de compatibilité (lecture plus facile):

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methodshttps://developer.mozilla.org/ en-US/docs/Web/HTTP/En-têtes/Contrôle d'accès, en-têtes autorisés

Au lieu de ce qui précède, de meilleures solutions, cela signifie que vous devez explicitement fournir chaque en-tête ou méthode que vous souhaitez autoriser.

0
Isaac

Je ne suis pas sûr que ce soit vraiment difficile, comme le dit djo.dadof2. L'une des réponses ci-dessus parle de l'utilisation de la console IIS, mais la question concerne le IIS Express. Pour être juste, il est question de déplacer OPTIONSVerbHandler plus haut, ce qui peut en fait fonctionner dans IIS Express, mais vous devez effacer tous les gestionnaires et les rajouter, sans console telle que IIS. _ a, c’est difficile car vous ne savez pas lesquels ajouter. A partir de cette réponse, Appelez le service WCF de JQuery: la requête OPTIONS cross-Origin donne l'erreur 400 , vous pouvez voir que tout ce dont vous avez besoin est de gérer la requête OPTIONS dans Global.asax.cs, Application_BeginRequest. J'ai ajouté

        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "content-type");

            HttpContext.Current.Response.End();
        }

Et ensemble avec 

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="null" />
  </customHeaders>
</httpProtocol>

dans la section webconfig system.webServer qui a fonctionné pour moi. Notez que j'ai utilisé content-type dans l'en-tête Access-Control-Allow-Headers pour faire correspondre ce que Firefox envoyait, et null dans le Access-Control-Allow-Origin car j'ouvrais une page html à partir du lecteur local.

0
S Waye