Обработка политики CORS для нескольких сред в ASP. NET Core 3.1 - PullRequest
3 голосов
/ 04 апреля 2020

Я пытаюсь «переключаться» между моими политиками CORS в зависимости от среды, в которой выполняется приложение.

У меня есть две политики, объявленные следующим образом:

services.AddCors(options =>
{
    options.AddPolicy(CORSPolicies.PublicApi,
        builder => builder
            .AllowAnyHeader()
            .WithMethods("POST", "GET")
            .WithOrigins("https://domain1.com", "https://domain2.com"));

    options.AddPolicy(CORSPolicies.Dev,
        builder => builder
            .AllowAnyHeader()
            .AllowAnyMethod()
            .AllowAnyOrigin());
});

Эти политики должны быть применимы только к нескольким контроллерам, поэтому я использую атрибут для их применения: политика

[ApiController]
[Route("api/[controller]")]
[Produces("application/json")]
[AllowAnonymous]
[EnableCors(CORSPolicies.PublicApi)]
public class PublicApiControllerBase : ControllerBase
{
}

PublicAPI должна быть действительной для производства, где домены будут фактически ограничены. Политика Dev разрешает все что угодно, так как я буду использовать это локально.

Я попытался установить политику по умолчанию равной Dev при условии условного запуска приложения, но поскольку EnableCorsAttribute переопределяет то, что определено app.UseCors(), оно не работает, так как будет использоваться политика PublicApi не важно что. Вот моя наивная попытка:

if (env.IsDevelopment())
{
    app.UseCors(CORSPolicies.Dev);
}
else
{
    app.UseCors();
}

Как я могу а) заставить мою политику PublicApi вести себя по-разному в зависимости от среды, в которой работает мое приложение, или б) условно применить политику PublicApi или Dev в зависимости от окружающая среда?

1 Ответ

4 голосов
/ 06 апреля 2020

Для варианта A вы можете вставить IWebHostEnvironment в конструктор Startup, захватить его как поле и использовать его в ConfigureServices.

Вот как это выглядит:

public class Startup
{
    private readonly IWebHostEnvironment env;

    public Startup(IWebHostEnvironment env)
    {
        this.env = env;
    }

    public void ConfigureService(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(CORSPolicies.PublicApi, builder =>
            {
                if (env.IsDevelopment())
                {
                    builder.AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowAnyOrigin();
                }
                else
                {
                    builder.AllowAnyHeader()
                        .WithMethods("POST", "GET")
                        .WithOrigins("https://domain1.com", "https://domain2.com");
                }
            });
        });

        // ...
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // ...

        app.UseCors();

        // ....
    }
}

При этом используется одна политика CORS, CORSPolicies.PublicApi, которая настроена в соответствии со средой.

...