Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling CORS policy for multiple environment in ASP.NET Core 3.1

I'm trying to "toggle" between my CORS policies depending on the environment the application is running.

I have two policies declared as follows:

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());
});

These policies should be only applicable to a few controllers so I'm using the attribute to apply them:

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

PublicAPI policy should be valid for production where domains are going to actually be restricted. Dev policy allows anything since I'll be using it locally.

I tried to set the default policy to be Dev conditionally on the application start, but since EnableCorsAttribute overrides what is defined by app.UseCors() it didn't work as PublicApi policy will be used no matter what. Here's my naive attempt:

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

How can I a) make my PublicApi policy behave differently depending on the environment my app is running or b) conditionally apply PublicApi or Dev policy depending on the environment?

like image 862
tucaz Avatar asked Apr 04 '20 19:04

tucaz


Video Answer


1 Answers

For option A, you can inject IWebHostEnvironment into the Startup constructor, capture it as a field, and use it in ConfigureServices.

Here's what that looks like:

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();

        // ....
    }
}

This uses a single CORS policy, CORSPolicies.PublicApi, which is configured according to the environment.

like image 68
Kirk Larkin Avatar answered Oct 18 '22 06:10

Kirk Larkin