60 votes

CORS dans .NET Core

Je suis en train d'activer la SCRO en .NET de Base dans le de cette façon:

    public IConfigurationRoot Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()
                                                                    .AllowAnyMethod()
                                                                     .AllowAnyHeader()));     
        services.AddMvc();            
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseCors("AllowAll");

        app.UseMvc(routes =>
         {
             routes.MapRoute(
                 name: "default",
                 template: "{controller=Home}/{action=Index}/{id?}");
         });

    }
}

Cependant, quand je suis en envoyant une demande à l'une de mes applications Angulaire 2 j'obtiens le fameux

"Non" Access-Control-Allow-Origin' en-tête est présent sur le demandé la ressource."

message d'erreur.

Je suis également à l'aide de l'Authentification Windows + WebListener. Si je vérifie avec facteur le seul en-têtes de réponse sont:

Content-Length →3533 Content-Type →application/json; charset=utf-8 Date →Fri, 14 Oct 2016 12:17:57 GMT Server →Microsoft-HTTPAPI/2.0

Donc il doit y avoir encore quelque chose de mal configuré. Toutes les propositions?

Si je supprime le outcommented ligne il fonctionne, mais j'ai besoin de l'Authentification Windows :-(

        var host = new WebHostBuilder()
            .UseWebListener()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            //.UseWebListener(options => options.Listener.AuthenticationManager.AuthenticationSchemes = AuthenticationSchemes.NTLM)
            .Build();

64voto

HockeyJ Points 1408

Supposons que vous avez la réponse, mais pour le bénéfice des chercheurs, j'ai eu le même problème avec la norme tutoriel sur la .NET de Base de la Scro.

L'une des nombreuses erreurs rencontrées:

XMLHttpRequest ne peut pas charger localhost:64633/api/blogs. Réponse en amont de demande ne passe pas de contrôle d'accès: Aucun "Access-Control-Allow-Origin' en-tête est présent sur le demandé de la ressource. Origine 'localhost:56573' est donc pas permis d'accès. La réponse avait le code d'état HTTP 500.

Après avoir joué, le code suivant a travaillé. Catégorie ci-dessous pour faciliter la compréhension de ce qui va où.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Cors.Infrastructure;

namespace NetCoreWebApiTesting
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

            if (env.IsEnvironment("Development"))
            {
                // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately.
                builder.AddApplicationInsightsSettings(developerMode: true);
            }

            builder.AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddApplicationInsightsTelemetry(Configuration);

            services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling =
                                                            Newtonsoft.Json.ReferenceLoopHandling.Ignore);

            // ********************
            // Setup CORS
            // ********************
            var corsBuilder = new CorsPolicyBuilder();
            corsBuilder.AllowAnyHeader();
            corsBuilder.AllowAnyMethod();
            corsBuilder.AllowAnyOrigin(); // For anyone access.
            //corsBuilder.WithOrigins("http://localhost:56573"); // for a specific url. Don't add a forward slash on the end!
            corsBuilder.AllowCredentials();

            services.AddCors(options =>
            {
                options.AddPolicy("SiteCorsPolicy", corsBuilder.Build());
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseApplicationInsightsRequestTelemetry();

            app.UseApplicationInsightsExceptionTelemetry();

            app.UseMvc();

            // ********************
            // USE CORS - might not be required.
            // ********************
            app.UseCors("SiteCorsPolicy");
        }
    }
}

Pour l'utiliser, vous pouvez ajouter l' EnableCorsAttribute sur le contrôleur ou sur la méthode. par exemple

[EnableCors("SiteCorsPolicy")]
[Route("api/[controller]")]
public class BlogsController : Controller
{

}

ou

// POST api/value
[EnableCors("SiteCorsPolicy")]
[HttpPost]
public HttpResponseMessage Post([FromBody]Blog value)
{
    // Do something with the blog here....

    var msg = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
    return msg;

}

Quand j'ai appelé ce en utilisant le code suivant (en utilisant la norme js/jQuery facile de copier et coller), la communication a cessé d'être rejeté.

function HandleClick() {

    var entityData = {
        "blogId": 2,
        "url": "http://blog.com/blog1",
        "posts": [
        {
            "postId": 3,
            "title": "Post 1-1",
            "content": "This is post 1 for blog 1",
            "blogId": 2
        },
        {
            "postId": 4,
            "title": "Post 1-2",
            "content": "This is post 2 for blog 1",
            "blogId": 2
        }
        ]
    };

    $.ajax({
        type: "POST",
        url: "http://localhost:64633/api/blogs",
        async: true,
        cache: false,
        crossDomain: true,
        data: JSON.stringify(entityData),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (responseData, textStatus, jqXHR) {
            var value = responseData;
        },
        error: function (responseData, textStatus, errorThrown) {
            alert('POST failed.');
        }
    });
}

34voto

sean Points 241

Cette façon fonctionne normalement, juste essayé sur angular2 avec .net de base. La question de l'OP est d'avoir, c'est que cela ne fonctionne pas avec l'authentification windows. Je suis en supposant que le middleware pour l'authentification windows qui se passe avant que la demande vient à travers, auquel cas sa rupture. Meilleur pari serait de voir si il y a un moyen d'activer l'authentification windows middleware après la scro middleware a traité à Configurer.

Ensuite, la commande serait

App.UseCors()

App.UseWindowsAuth()

App.UseMVC()

Ils doivent se produire dans cet ordre pour que cela fonctionne.

public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options => options.AddPolicy("AllowAll", p => p.AllowAnyOrigin()
                                                                    .AllowAnyMethod()
                                                                     .AllowAnyHeader()));     
        services.AddMvc();            
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseCors("AllowAll");

        app.UseMvc(routes =>
         {
             routes.MapRoute(
                 name: "default",
                 template: "{controller=Home}/{action=Index}/{id?}");
         });

    }

14voto

Stefan de Groot Points 200

Ce qui manque à la documentation, c'est l'importance de .AllowAnyMethod (). S'il n'est pas présent, le no redouté 'Access-Control-Allow-Origin' continuera à vous déranger. Dans votre code, c'est là, donc je suppose que vous avez manqué de définir le bon en-tête dans l'application côté client.

Je l'ai personnellement fait fonctionner en permettant à tous:

 app.UseCors(b => b.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());
 

Et mon poste angulaire fonctionne comme:

 post(model) {

    let headers = new Headers({
      'Content-Type':'application/json; charset=utf-8;' 
      ,'Accept':'*/*'
    });


    let options = new RequestOptions({ headers: headers });
    let body = JSON.stringify(model);

    return this.http.post(
      'http://localhost:58847/api/TestPost', body, options)
      .map((response: Response) => {
        let res = response.json();
        return res;
      }
    );
}
 

Après cela, vous progressez graduellement en spécifiant les origines, etc.

14voto

Tanver Hasan Points 306

Dans ASPNET CORE 2.0, ce qui suit fonctionne pour moi

    public void ConfigureServices(IServiceCollection services)
    {

        services.Configure<MvcOptions>(options =>
        {
            options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));
        });
        services.AddCors(options =>
        {
            options.AddPolicy("AllowSpecificOrigin",
                builder => builder.WithOrigins("http://localhost:5000").AllowAnyHeader()
                .AllowAnyMethod());
        });

        services.AddMvc()
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {

        loggerFactory.AddConsole();
        loggerFactory.AddDebug(LogLevel.Information);

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        // Shows UseCors with named policy.
        app.UseCors("AllowSpecificOrigin");

        app.UseStaticFiles();
        app.UseAuthentication();


        app.UseMvcWithDefaultRoute();
    }
}
 

2voto

Gerfaut Points 74

La réponse de @HockeyJ est correcte, mais vous pouvez faire quelque chose de plus concis si vous le souhaitez.

 public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    //Or if you want to chose what to include
    services.AddMvcCore()
            .AddCors()
            (...)
}


public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    //Cors
    app.UseCors(builder =>
    {
        builder.AllowAnyHeader();
        builder.AllowAnyMethod();
        builder.AllowCredentials();
        builder.AllowAnyOrigin(); // For anyone access.
        //corsBuilder.WithOrigins("http://localhost:56573"); // for a specific url.
     });
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X