CORS в MVC

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7

Последнее обновление: 22.12.2019

В прошлых темах было рассмотрено использование CORS в простом проекте ASP.NET Core по типу Empty. Но в ASP.NET Core MVC есть некоторые дополнительные возможности, поэтому рассмотрим их отдельно.

В MVC можно настроить CORS глобально для всего приложения, отдельно для каждого контроллера или даже отдельно для каждого действия контроллера.

Само подключение CORS осуществляется также, как и в проекте Empty с помощью метода AddCors. В частности, определим в проекте MVC следующий класс Startup:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace CorsMvcApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddCors(options =>
            {
                options.AddPolicy("AllowAllOrigin", builder => builder.AllowAnyOrigin());
            });
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseDeveloperExceptionPage();

            app.UseStaticFiles();
            app.UseRouting();

            app.UseCors();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Здесь определяется политика "AllowAllOrigin", при которой приложение будут принимать запросы от всех адресов.

Настройка для действия контроллера

Для применения CORS к методу контроллера используется атрибут [EnableCors]:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Cors;

public class HomeController : Controller
{
	[EnableCors("AllowAllOrigin")]
	public IActionResult Index()
	{
		return Content("Hello from ASP.NET Core MVC");
	}
	
	public IActionResult Test()
	{
		return Content("Test from ASP.NET Core MVC");
	}
}

Атрибуту EnableCors передается название политики, которая была определена в классе Startup через вызов services.AddCors, то есть AllowAllOrigin. И теперь сторонние приложения могут обращаться к этому методу, естественно, если их запросы соответствуют политике AllowAllOrigin.

В отличие от метода Index другой метод контроллера - метод Test атрибута EnableCors не имеет, соответственно мы не сможем обратиться к методу Test из других приложений. То есть с помощью данного атрибута мы можем детально указать, к каким имеенно ресурсам приложения мы хотим предоставить доступ

Настройка для контроллера

Чтобы распространить действие CORS на весь контроллер, к нему также применяется атрибут EnableCors, в который передается название политики:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Cors;


namespace CorsMvcApp.Controllers
{
    [EnableCors("AllowAllOrigin")]
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return Content("Hello from ASP.NET Core MVC");
        }

        public IActionResult Test()
        {
            return Content("Test from ASP.NET Core MVC");
        }
    }
}

Теперь политика AllowAllOrigin применяется ко всем методам контроллера.

Установка для отдельных маршрутов

При использовании метода app.UseEndpoints() для определения маршрутов мы можем указать настройки CORS для отдельных маршрутов с помощью метода RequireCors():

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace CorsMvcApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddCors(options =>
            {
                options.AddPolicy("AllowAllOrigin", builder => builder.AllowAnyOrigin());
            });
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseDeveloperExceptionPage();

            app.UseStaticFiles();
            app.UseRouting();

            app.UseCors();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}")
                .RequireCors(options => options.AllowAnyOrigin());

                // или передать название политики
                endpoints.MapControllerRoute(
                    name: "api",
                    pattern: "api/{controller=Home}/{action=Index}/{id?}")
                .RequireCors("AllowAllOrigin");
            });
        }
    }
}

Глобальная настройка

Чтобы распространить политику Cors на все приложение со всеми его контроллерами, достаточно в метод UseCors передать соответствующие настройки:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Cors;

namespace CorsMvcApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddCors();
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseStaticFiles();
            app.UseRouting();

			// Установка CORS для всех ресурсов
            app.UseCors(options => options.AllowAnyOrigin());

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

В этом случае все методs всех контроллеров будет иметь возможность принимать запросы от всех других приложений. И нам не надо устанавливать для методов и контроллеров атрибут EnableCors. Если мы вдруг захотим исключить какой-то метод или контроллер из применения CORS, то к этому методу или контроллеру следует применить атрибут [DisableCors]:

public class HomeController : Controller
{
	[DisableCors]
	public IActionResult Index()
	{
		return Content("Hello from ASP.NET Core MVC");
	}
}

Также если мы захотим применить к какому-то методу или контроллеру какую-ту специфическую политику CORS, то опять мы можем применять атрибут EnableCors. При этом настройки для метода контроллера имеют больший приоритет чем настройки для контроллера. А настройки для контроллера имеют больший приоритет, чем глобальные настройки.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850