web-dev-qa-db-fra.com

Définition de l'accès-contrôle-autorisation-origine dans ASP.Net MVC - méthode la plus simple possible

J'ai une méthode d'action simple, qui retourne du json. Il fonctionne sur ajax.example.com. Je dois accéder à cela depuis un autre site someothersite.com.

Si j'essaie de l'appeler, je reçois le résultat attendu ...:

Origin http://someothersite.com is not allowed by Access-Control-Allow-Origin.

Je connais deux façons de contourner ce problème: JSONP et de créer un custom HttpHandler to Définir l'en-tête.

N'y a-t-il pas un moyen plus simple?

N’est-il pas possible pour une action simple de définir une liste des origines autorisées - ou d’autoriser tout le monde? Peut-être un filtre d'action?

Optimal serait ...:

return json(mydata, JsonBehaviour.IDontCareWhoAccessesMe);
190
Kjensen

Pour les contrôleurs ASP.NET MVC simples

Créer un nouvel attribut

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
        base.OnActionExecuting(filterContext);
    }
}

Marquez votre action:

[AllowCrossSiteJson]
public ActionResult YourMethod()
{
    return Json("Works better?");
}

Pour API Web ASP.NET

using System;
using System.Web.Http.Filters;

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Response != null)
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");

        base.OnActionExecuted(actionExecutedContext);
    }
}

Marquez un contrôleur API complet:

[AllowCrossSiteJson]
public class ValuesController : ApiController
{

Ou appels d’API individuels:

[AllowCrossSiteJson]
public IEnumerable<PartViewModel> Get()
{
    ...
}

Pour Internet Explorer <= v9

IE <= 9 ne supporte pas CORS. J'ai écrit un code javascript qui acheminera automatiquement ces demandes via un proxy. Tout est transparent à 100% (il suffit d'inclure mon proxy et le script).

Téléchargez-le avec nuget corsproxy et suivez les instructions fournies.

Article de blog | Code source

353
jgauffin

Si vous utilisez IIS 7+, vous pouvez placer un fichier web.config à la racine du dossier avec ceci dans la section system.webServer:

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

Voir: http://msdn.Microsoft.com/en-us/library/ms178685.aspx Et: http://enable-cors.org/#how-iis7

114
LaundroMatt

J'ai rencontré un problème où le navigateur a refusé de diffuser le contenu qu'il avait récupéré lorsque la demande avait été transmise aux cookies (par exemple, le xhr avait son withCredentials=true) et le site avait Access-Control-Allow-Origin défini sur *. (L'erreur dans Chrome était la suivante: "Impossible d'utiliser un caractère générique dans Access-Control-Allow-Origin lorsque l'indicateur d'informations d'identification est true.")

En me basant sur la réponse de @jgauffin, j’ai créé ceci: c’est un moyen de contourner le contrôle de sécurité du navigateur en question, donc attention.

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // We'd normally just use "*" for the allow-Origin header, 
        // but Chrome (and perhaps others) won't allow you to use authentication if
        // the header is set to "*".
        // TODO: Check elsewhere to see if the Origin is actually on the list of trusted domains.
        var ctx = filterContext.RequestContext.HttpContext;
        var Origin = ctx.Request.Headers["Origin"];
        var allowOrigin = !string.IsNullOrWhiteSpace(Origin) ? Origin : "*";
        ctx.Response.AddHeader("Access-Control-Allow-Origin", allowOrigin);
        ctx.Response.AddHeader("Access-Control-Allow-Headers", "*");
        ctx.Response.AddHeader("Access-Control-Allow-Credentials", "true");
        base.OnActionExecuting(filterContext);
    }
}
19
Ken Smith

C’est très simple, il suffit d’ajouter ceci dans web.config

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="http://localhost" />
      <add name="Access-Control-Allow-Headers" value="X-AspNet-Version,X-Powered-By,Date,Server,Accept,Accept-Encoding,Accept-Language,Cache-Control,Connection,Content-Length,Content-Type,Host,Origin,Pragma,Referer,User-Agent" />
      <add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" />
      <add name="Access-Control-Max-Age" value="1000" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Dans Origin, placez tous les domaines ayant accès à votre serveur Web, Dans les en-têtes placez tous les en-têtes possibles pouvant être utilisés par toutes les requêtes ajax http, Dans les méthodes placez toutes les méthodes que vous autorisez sur votre serveur.

cordialement :) 

14
Zvonimir Tokic

Parfois, le verbe OPTIONS pose aussi des problèmes 

Simplement: Mettez à jour votre web.config avec ce qui suit 

<system.webServer>
    <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Origin" value="*" />
          <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

Et mettez à jour les en-têtes Webservice/Controller avec httpGet et httpOptions 

// GET api/Master/Sync/?version=12121
        [HttpGet][HttpOptions]
        public dynamic Sync(string version) 
        {
8
Bishoy Hanna

WebAPI 2 dispose désormais d'un package pour CORS pouvant être installé à l'aide de: Install-Package Microsoft.AspNet.WebApi.Cors -pre -project WebServic 

Une fois ceci installé, suivez ceci pour le code: http://www.asp.net/web-api/overview/security/enabling-cross-Origin-requests-in-web-api

7
Tarun

Ajoutez cette ligne à votre méthode, si vous utilisez une API.

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
3
Gopichandar
    public ActionResult ActionName(string ReqParam1, string ReqParam2, string ReqParam3, string ReqParam4)
    {
        this.ControllerContext.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin","*");
         /*
                --Your code goes here --
         */
        return Json(new { ReturnData= "Data to be returned", Success=true }, JsonRequestBehavior.AllowGet);
    }
1
Pranav Labhe

Il y a différentes façons de passer le En-têtes de contrôle d'accès.

  • Comme jgauffin l'a expliqué, nous pouvons créer un nouvel attribut.
  • Comme LaundroMatt l'a expliqué, nous pouvons ajouter le fichier web.config.
  • Une autre solution consiste à ajouter du code comme ci-dessous dans le fichier webApiconfig.cs.

    config.EnableCors (new EnableCorsAttribute ("", en-têtes: "", méthodes: "*", exposureHeaders: "TestHeaderToExpose") {SupportsCredentials = true}); 

Ou nous pouvons ajouter le code ci-dessous dans le fichier Global.Asax.

protected void Application_BeginRequest()
        {
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                //These headers are handling the "pre-flight" OPTIONS call sent by the browser
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
                HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "TestHeaderToExpose");
                HttpContext.Current.Response.End();
            }
        }

Je l'ai écrit pour les options. Veuillez modifier les mêmes selon vos besoins.

Bonne codage !!

1
Developer

Dans Web.config, entrez les informations suivantes

<system.webServer>
<httpProtocol>
  <customHeaders>
    <clear />     
    <add name="Access-Control-Allow-Credentials" value="true" />
    <add name="Access-Control-Allow-Origin" value="http://localhost:123456(etc)" />
  </customHeaders>
</httpProtocol>
0
Elvis

Si vous utilisez IIS, je vous suggérerais d'essayer IIS module CORS .
Il est facile à configurer et fonctionne pour tous les types de contrôleurs.

Voici un exemple de configuration: 

    <system.webServer>
        <cors enabled="true" failUnlistedOrigins="true">
            <add Origin="*" />
            <add Origin="https://*.Microsoft.com"
                 allowCredentials="true"
                 maxAge="120"> 
                <allowHeaders allowAllRequestedHeaders="true">
                    <add header="header1" />
                    <add header="header2" />
                </allowHeaders>
                <allowMethods>
                     <add method="DELETE" />
                </allowMethods>
                <exposeHeaders>
                    <add header="header1" />
                    <add header="header2" />
                </exposeHeaders>
            </add>
            <add Origin="http://*" allowed="false" />
        </cors>
    </system.webServer>
0
olsh