Search code examples
c#reactjscorsauth0

CORS Issue - Between Dev and Prod


I've a problem with CORS when trying to run my ReactJS app, with my C# API when this API is hosted on my local IIS Server using HTTPS.

Here my setup detail

  • Front-End: ReactJS, TailWind CSS
  • Back-End: C# .Net 8, SQL DB, Hosted on a Local machine IIS.
  • Auth0 As IDProvider
  • I've my own domain Name, let say "MyDomain.ca"
  • SSL Cetificat Install on IIS

When I'm working on my Dev computer and I use my API that is also running on my Dev Machine "https://localhost:7248/api", The Web Application is working as suppose. The CORS do not block me.

When I change the API URL for my domain https://MyDomain.ca/API CORS keep bloking me.

I've install Swagger with the API, so I can do call to API. I can do Login with it whitout any problem. Swager respoind me with:

access-control-allow-credentials: true 
access-control-allow-origin: https://MyDomain.ca  
cache-control: no-cache,no-store  
content-type: application/json; charset=utf-8  
date: Fri,06 Dec 2024 19:15:11 GMT  
expires: Thu,01 Jan 1970 00:00:00 GMT  
pragma: no-cache  
server: Microsoft-IIS/10.0  
vary: Origin  
x-firefox-spdy: h2  
x-powered-by: ASP.NET

But when I try wo do the login with my React App running from http://localhost:5173/ , I got error like those in the Browser Console

XHR OPTIONS https://myAuth0Domain.us.auth0.com/authorize?...blah.. CORS Missings Origin

And Also:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at

I've set my domain in the corresponding setting Auth0 application manager, Application Login URI: https://MyDomain.ca Allowed CallBack URL: https://MyDomain.ca/api/callback, http://localhost:5173/api/auth/callback Allowed Web Origins: https://MyDomain.ca,http://localhost:5173

I've also set the origin in my .net API, like this:

      // [More code]

      builder.Services.AddHttpClient();
      builder.Services.AddCors(options =>
      {
          options.AddPolicy("AllowSpecificOrigin", corsBuilder =>
                  corsBuilder.WithOrigins("http://localhost:5173", 
                                          "https://MyDomain.ca")
                              .AllowAnyHeader()
                              .AllowAnyMethod()
                              .AllowCredentials());
      });
      // [More code]
      app.UseCors("AllowSpecificOrigin");
      // [More code]

I thing that the

access-control-allow-origin: https://MyDomain.ca  

is missing from the header when I try the login from my WebApplication. But I don't know what to do to fix this.

I need some help to resolve my problem.

Thank Hugo


Solution

  • The error is statting was CORS Error, but it has nothing to do with CORS in fact.

    I've revised my whole process, an find many bug..

    • Auth0 M2M Application was missing (I did some clean up and deleted thing that should not have)
    • The way I have wrap the js fetch method was bad at some specific places
    • I've revised the way Auth0 ClientId, Secret was set and configured wasn't clear, so I fix this
    • in .NET, the ordre in witch I was registring Authentication/Autorization/ useRouting was incorrect It shoul be
    var app = builder.Build();
    app.UseCors("AllowSpecificOrigins");
    app.UseRouting(); 
    app.UseAuthentication();
    app.UseAuthorization();
    ...
    app.UseMiddleware(...) // If needed
    ...
    app.UseSwagger(); // If needed
    app.UseSwaggerUI(); // If needed
    ...
    app.MapControllers();
    ...
    app.Run();
    

    then

    var builder = WebApplication.CreateBuilder(args);
    ...
            builder.Services
                .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
                {
                    options.LoginPath = "/api/auth/login";
                    options.LogoutPath = "/api/auth/logout"; // Redirect for logout
                    options.Cookie.Name = "PosterityCookie";
                    options.Cookie.SameSite = SameSiteMode.None; // Ensure SameSite is set to None
                    options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // Ensure the cookie is sent over HTTPS
    
                    options.Events.OnSigningIn = async context =>
                    {
                        Debug.WriteLine($" options.Events.OnSigningIn {context}");
                        await Task.CompletedTask;
                    };
                    options.Events.OnValidatePrincipal = async context =>
                    {
                        Debug.WriteLine($" options.Events.OnValidatePrincipal {context}");
                        await Task.CompletedTask;
                    };
                })
                .AddOpenIdConnect("Auth0", options =>
                {
                    var auth0OpenIdConfiguration = Auth0OpenIdConfiguration.CreateFromConfig(builder.Configuration);
                    options.Authority = auth0OpenIdConfiguration.Authority;
                    options.ClientId = auth0OpenIdConfiguration.ClientId;
                    options.ClientSecret = auth0OpenIdConfiguration.ClientSecret;
                    options.ResponseType = "code";
                    options.SaveTokens = true;
    
                    options.Scope.Clear();
                    options.Scope.Add("openid");
                    options.Scope.Add("profile");
                    options.Scope.Add("email");
    
                    options.CallbackPath = "/api/auth/callback";
                    options.ClaimsIssuer = "Auth0";
    
                    // Capture authentication event
                    options.Events = OpenIdConnectEventsProvider.GetOpenIdConnectEvents();
    
                })
    
    

    What helped me a lot is when a started to retry what I was attempting to do, but in a fresh bare bone simplified WorkBench Project, Javascript and .NET

    I ate a lot of dirt before thing start working and I learned a lot