Base solution for your next web application
Open Closed

CORS Issue #9693


User avatar
0
mahendra created

Hi Support,

We have a multitenant application deployed in Azure. Both backend and frontend are deployed on the same AppService but on different slots. We have setup the CorsOrigins settings as "https://*.tagrain.net" in the AppService Configuration of the backend and all is good till here.

The moment we started the feature of signalR, and browse the site (say abc.tagrain.net), we started getting the following error after login page.

Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute. Error: Failed to complete negotiation with the server: Error Error: Failed to start the connection: Error

While googling we came across to the below link that talks about CORS setting in Azure App. https://support.aspnetzero.com/QA/Questions/7574/Chat-not-connecting-after-deploying-to-Azure

We followed this link and tick the check box "Enable Access-Control-Allow-Credentials" and removed the * from the Allowed Origins

Now when we browse the site (abc.tagrain.net), we did not get the error of 'Access-Control-Allow-Credentials'.....we thought all is good now.

But now when we browse the site tagrain.net (I mean without tenancyName prefix), we are getting the below error:

Access to XMLHttpRequest at 'https://tagrainretail-prodserver.azurewebsites.net//AbpUserConfiguration/GetAll?d=1601442505849' from origin 'https://abintest15.tagrain.net' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

polyfills.df90ed90577f0abf84f8.js:1 GET https://tagrainretail-prodserver.azurewebsites.net//AbpUserConfiguration/GetAll?d=1601442505849 net::ERR_FAILED

Please help....

Regards, Mahendra


8 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @mahendra

    We suggest to use AspNet Zero's CORS policy and not Azure's. Could you change it backto that and see if there are any error logs in the server side Logs.txt file when you get this error next time ?

    Thanks,

  • User Avatar
    0
    mahendra created

    I revert the Azure's CORS policy back. see the screen shot below. Earlier Enable Access-Control-Allow-Credentials was ticked.

    Below is the setting of AZPNetZero's CORS.

    Now when we browse the site then after login we get the CORS error. Please see below screen shot. This error was not coming till the time we had not enabled the signalR.

  • User Avatar
    0
    mahendra created

    Thought, you may want to see the startup.cs file.

    public IServiceProvider ConfigureServices(IServiceCollection services)
            {
                //MVC
                services.AddControllersWithViews(options =>
                {
                    options.Filters.Add(new AbpAutoValidateAntiforgeryTokenAttribute());
                }).AddNewtonsoftJson();
    
                
                services.AddSignalR(options => { options.EnableDetailedErrors = true; });
    
    
                //Azure:SignalR:ConnectionString is the default configuration key that SignalR looks for to establish a connection.
                //services.AddSignalR().AddAzureSignalR(@"Endpoint=https://ivendwebsignalr.service.signalr.net;AccessKey=+oTw1tBp2lEbDpJ2e/Pyl3LKreDfqQfvNEemaOPFOmo=;Version=1.0;");
    
    
                //Configure CORS for angular2 UI
                services.AddCors(options =>
                {
                    options.AddPolicy(DefaultCorsPolicyName, builder =>
                    {
                        //App:CorsOrigins in appsettings.json can contain more than one address with splitted by comma.
                        builder
                            .WithOrigins(
                                // App:CorsOrigins in appsettings.json can contain more than one address separated by comma.
                                _appConfiguration["App:CorsOrigins"]
                                    .Split(",", StringSplitOptions.RemoveEmptyEntries)
                                    .Select(o => o.RemovePostFix("/"))
                                    .ToArray()
                            )
                            .SetIsOriginAllowedToAllowWildcardSubdomains()
                            .AllowAnyHeader()
                            .AllowAnyMethod()
                            .AllowCredentials();
                    });
                });
    
                IdentityRegistrar.Register(services);
                AuthConfigurer.Configure(services, _appConfiguration);
    
                //Identity server
                if (bool.Parse(_appConfiguration["IdentityServer:IsEnabled"]))
                {
                    IdentityServerRegistrar.Register(services, _appConfiguration, options =>
                         options.UserInteraction = new UserInteractionOptions()
                         {
                             LoginUrl = "/UI/Login",
                             LogoutUrl = "/UI/LogOut",
                             ErrorUrl = "/Error"
                         });
                }
    
                if (WebConsts.SwaggerUiEnabled)
                {
                    //Swagger - Enable this line and the related lines in Configure method to enable swagger UI
                    services.AddSwaggerGen(options =>
                    {
                        options.SwaggerDoc("v1", new OpenApiInfo() { Title = "iVend API", Version = "v1" });
                        options.DocInclusionPredicate((docName, description) => true);
                        options.ParameterFilter<SwaggerEnumParameterFilter>();
                        options.SchemaFilter<SwaggerEnumSchemaFilter>();
                        options.OperationFilter<SwaggerOperationIdFilter>();
                        options.OperationFilter<SwaggerOperationFilter>();
                        options.CustomDefaultSchemaIdSelector();
                    });
                }
    
                //Recaptcha
                services.AddRecaptcha(new RecaptchaOptions
                {
                    SiteKey = _appConfiguration["Recaptcha:SiteKey"],
                    SecretKey = _appConfiguration["Recaptcha:SecretKey"]
                });
    
                //if (WebConsts.HangfireDashboardEnabled)
                //{
                //    //Hangfire(Enable to use Hangfire instead of default job manager)
                //    services.AddHangfire(config =>
                //    {
                //        config.UseSqlServerStorage(_appConfiguration.GetConnectionString("Default"));
                //    });
                //}
    
                if (WebConsts.GraphQL.Enabled)
                {
                    services.AddAndConfigureGraphQL();
                    services.AddSingleton<QueryContainer>();
                }
    
                if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksEnabled"]))
                {
                    services.AddAbpZeroHealthCheck();
    
                    var healthCheckUISection = _appConfiguration.GetSection("HealthChecks")?.GetSection("HealthChecksUI");
    
                    if (bool.Parse(healthCheckUISection["HealthChecksUIEnabled"]))
                    {
                        services.Configure<HealthChecksUISettings>(settings =>
                        {
                            healthCheckUISection.Bind(settings, c => c.BindNonPublicProperties = true);
                        });
                        services.AddHealthChecksUI();
                    }
                }
    
                //Configure Abp and Dependency Injection
                return services.AddAbp<iVendWebHostModule>(options =>
                {
                    //Configure Log4Net logging
                    options.IocManager.IocContainer.AddFacility<LoggingFacility>(
                        f => f.UseAbpLog4Net().WithConfig("log4net.config")
                    );
    
                    options.PlugInSources.AddFolder(Path.Combine(_hostingEnvironment.WebRootPath, "Plugins"), SearchOption.AllDirectories);
                });
            }
    
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
            {
    
                Clock.Provider = ClockProviders.Utc;
                
                
                //Initializes ABP framework.
                app.UseAbp(options =>
                {
                    options.UseAbpRequestLocalization = false; //used below: UseAbpRequestLocalization
                });
    
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseStatusCodePagesWithRedirects("~/Error?statusCode={0}");
                    app.UseExceptionHandler("/Error");
                }
    
                app.UseStaticFiles();
                app.UseRouting();
    
                app.UseCors(DefaultCorsPolicyName); //Enable CORS!
    
                app.UseAuthentication();
                //app.UseAuthorization();
                app.UseJwtTokenMiddleware();
    
                if (bool.Parse(_appConfiguration["IdentityServer:IsEnabled"]))
                {
                    //app.UseJwtTokenMiddleware("IdentityBearer");
                    app.UseIdentityServer();
                }
    
                app.UseAuthorization();
    
                using (var scope = app.ApplicationServices.CreateScope())
                {
                    if (scope.ServiceProvider.GetService<DatabaseCheckHelper>().Exist(_appConfiguration["ConnectionStrings:Default"]))
                    {
                        app.UseAbpRequestLocalization();
                    }
                }
    
                //if (WebConsts.HangfireDashboardEnabled)
                //{
                //    //Hangfire dashboard &server(Enable to use Hangfire instead of default job manager)
                //    app.UseHangfireDashboard(WebConsts.HangfireDashboardEndPoint, new DashboardOptions
                //    {
                //        Authorization = new[] { new AbpHangfireAuthorizationFilter(AppPermissions.Pages_Administration_HangfireDashboard) }
                //    });
                //    app.UseHangfireServer();
                //}
    
                if (bool.Parse(_appConfiguration["Payment:Stripe:IsActive"]))
                {
                    StripeConfiguration.ApiKey = _appConfiguration["Payment:Stripe:SecretKey"];
                }
    
                if (WebConsts.GraphQL.Enabled)
                {
                    app.UseGraphQL<MainSchema>();
                    if (WebConsts.GraphQL.PlaygroundEnabled)
                    {
                        app.UseGraphQLPlayground(
                            new GraphQLPlaygroundOptions()); //to explorer API navigate https://*DOMAIN*/ui/playground
                    }
                }
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapHub<AbpCommonHub>("/signalr");
                    //endpoints.MapHub<ChatHub>("/signalr-chat");
                    //endpoints.MapHub<IVendWebHub>("/ivendwebhub");
    
                    endpoints.MapControllerRoute("defaultWithArea", "{area}/{controller=Home}/{action=Index}/{id?}");
                    endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
    
                    if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksEnabled"]))
                    {
                        endpoints.MapHealthChecks("/healthz", new HealthCheckOptions()
                        {
                            Predicate = _ => true,
                            ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
                        });
                    }
                });
    
                if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksEnabled"]))
                {
                    if (bool.Parse(_appConfiguration["HealthChecks:HealthChecksUI:HealthChecksUIEnabled"]))
                    {
                        app.UseHealthChecksUI();
                    }
                }
    
                if (WebConsts.SwaggerUiEnabled)
                {
                    // Enable middleware to serve generated Swagger as a JSON endpoint
                    app.UseSwagger();
                    // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
                    
                    app.UseSwaggerUI(options =>
                    {
                        options.SwaggerEndpoint(_appConfiguration["App:SwaggerEndPoint"], "Tagrain API V1");
                        options.IndexStream = () => Assembly.GetExecutingAssembly()
                            .GetManifestResourceStream("CitiXsys.iVend.Web.wwwroot.swagger.ui.index.html");
                        options.InjectBaseUrl(_appConfiguration["App:ServerRootAddress"]);
                    }); //URL: /swagger
                }
            }
    
  • User Avatar
    0
    mahendra created

    Not getting any error in Server's log.txt file

  • User Avatar
    0
    mahendra created

    This has been fixed....please don't bother

  • User Avatar
    0
    bdadmin created

    Hello, Can you tell me what you did to fix this issue. We are also getting a cors error after upgrading.

  • User Avatar
    0
    mahendra created

    Hi,

    We did two things:

    1. Didn't use Azure's CORS settings. See the screen shot below.

    1. Set the following in App:CorsOrigins settings. Here sequence matters. https://<mydomain>.net, https://*.<mydomain>.net

    Regards, Mahendra

  • User Avatar
    0
    TimMackey created

    After 'Start' or 'Reset' of the server in Azure, the Swagger page must be run one time (then closed) to avoid CorsOrigin errors.