0

Are there an explicit "Access-Control-Allow-Credentials" attribute to explicitly allow credentials to be sent with a request to a specific client site?

I have tried the following

var  MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddCors(options =>
{
    options.AddPolicy(name: MyAllowSpecificOrigins,
                      builder =>
                      {
                          builder.WithOrigins("http://my-account-name.github.io",
                                              "http://my-account-name.github.io/My-repository",
                                              "https://my-account-name.github.io",
                                              "https://my-account-name.github.io/My-repository");
                      });
});
...

app.UseCors(MyAllowSpecificOrigins);

Not working solution source

And I get the "CORS" policy restriction in Chrome console nevertheless for those request that include credential headers and / or authorize cookies. Other requests (that don't include credentials) are passing fine with cors fetch() from JS.

Ivan Silkin
  • 381
  • 1
  • 7
  • 15
  • 1
    I noticed you mentioned `credential headers and authorize cookies`, maybe [this link](https://stackoverflow.com/questions/46288437/set-cookies-for-cross-origin-requests) will help you. – Chen Nov 29 '22 at 08:39
  • @Chen, yes, this helped a lot! I have also figured out that there is a `Cookie.SameSite = SameSiteMode.None;` configuration property that lets cookies not be blocked by the browser's CORS policy (Lax / Strict instead of None). – Ivan Silkin Jan 25 '23 at 19:44

1 Answers1

0

The complete solution to the CORS Cookie Authorization is the SameSite = None; cookie policy (which you have to tell the browser explicitly from your server)

// Controller.cs
    [EnableCors("_allowSpecific")] // !!!
    public class YourController : Controller
// ...

// Startup.cs (.Net 5) / Program.cs (.Net 6-7 +)
        string MyAllowSpecificOrigins = "_allowSpecific";

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSession(options =>
            {
                options.Cookie.SameSite = Microsoft.AspNetCore.Http.SameSiteMode.None; // !!!
            });
            services.AddCors(options => {
                options.AddPolicy(name: MyAllowSpecificOrigins,
                    policy => { policy.WithOrigins( "http://your-domain.your-site.com", "https://your-domain.your-site.io", "http://your-domain.your-site.io"
#if DEBUG // Use this for debugging CORS in NPM on another localhost port 
                        , "http://localhost:8081", "https://localhost:8081", "http://127.0.0.1:8081", "http://192.168.1.64:8081"
#endif
                    ).AllowAnyHeader().AllowAnyMethod().AllowCredentials(); 
                });
            });
            services.Configure<CookiePolicyOptions>(options => {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true; 
                options.MinimumSameSitePolicy = SameSiteMode.None; // !!!
            });

            // ADD your services, DbContexts, Identity, Configure<IdentityOptions>, AddDefaultIdentity<IdentityUser>, AddRoles<IdentityRole>, AddEntityFrameworkStores<ApplicationDbContext>, ConfigureApplicationCookie, AddDatabaseDeveloperPageExceptionFilter, AddSingleton<IHttpContextAccessor>, AddRazorPages, AddControllersWithViews, AddLogging, 

            services.ConfigureApplicationCookie(options => {
                // Cookie settings
                options.Cookie.SameSite = SameSiteMode.None; // !!!
                options.Cookie.HttpOnly = true;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(10000);
                options.SlidingExpiration = true;
            });
        }

        public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IWebHostEnvironment env, Microsoft.Extensions.Hosting.IHostApplicationLifetime appLifetime)
        {
            // ...
            app.UseCookiePolicy(new CookiePolicyOptions {
                MinimumSameSitePolicy = SameSiteMode.None // !!!
            });
            // app.UseRouting(); ...

            app.UseCors(MyAllowSpecificOrigins); // ? 1) not sure whether you need to use both, but it works
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseCors(MyAllowSpecificOrigins); // ? 2) not sure if you need to use both, but it works

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

Not only this setup will allow you to use CORS autherization (using cookie headers), this will also allow Chrome to block any request from other than "_allowSpecific" origins. I had to spend almost a year to figure this out.

Ivan Silkin
  • 381
  • 1
  • 7
  • 15