0

When I deploy the back end at an HTTPS domain, I can't talk to it from the front end. It worked on an HTTP domain.

It seems to be a 502 bad gateway so I think something to do with the EB proxy which I have not been controlling so I will look into how to do so:

enter image description here

program.cs:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
                webBuilder.UseUrls("https://*:5002");
                webBuilder.UseUrls("http://*:5002");
            });
}

startup.cs

services.AddCors(options =>
{
    options.AddPolicy("AllowAll", builder =>
    {
        builder
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader();
    });
});

app.UseHttpsRedirection();
app.UseRouting();

// app.UseCors(options =>
// {
//     options.SetIsOriginAllowedToAllowWildcardSubdomains()
//         .AllowAnyHeader()
//         .AllowAnyMethod()
//         .AllowCredentials()
//         .Build();
// }).Build();

app.UseCors(b => b.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());

endpoint:

[EnableCors("AllowAll")]
[HttpGet("{id}")]
[AllowAnonymous]
public Task<ServiceResponse<UserDto>> Fetch([FromQuery(Name = "id")] string id)
{
    var user = service.Fetch(id);
    return user;
}

I think it is only a CORS issue now, because I see CORS errors on my http requests to my asp.net server in the chrome inspector:

Access to XMLHttpRequest at 'https://vepo-qa.com/users/%7Bid%7D?id=A96BqrMzB6fqPH7aH8js6cmFKrt2' from origin 'https://vepo-qa.web.app' 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.

When you see how many things I am doing for CORS, there's just no way the issue is with my asp.net core app CORS configs...wtf is going on with the CORS errors?

UPDATE: My server is also showing this now:

"OPTIONS /allvgnitmests/postsearchall HTTP/1.1" 502 552 "https://vepo-qa.web.app/"

https://vepo-qa.web.app/ is my front end! So I think I am making progress, as it is talking, and saying no, instead of not actually hearing. The front end is saying CORS issue, which lines up with seeing an OPTIONS request and nothing else. Does app.UseCors() stop working once it is deployed on an HTTPS domain? UseCors was working when it was deployed at an HTTP domain.

My whole startup.cs:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Security.Claims;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using FirebaseAdmin;
using Google.Apis.Auth.OAuth2;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using NetTopologySuite.IO.Converters;
using Npgsql;
using Vepo.Data;
using Vepo.DataContext;
using Vepo.Domain;
using Vepo.Infrastructure;
using Vepo.Services;
using Yarp.ReverseProxy.Forwarder;
using Yarp.ReverseProxy.Transforms;

namespace Vepo.Web
{
    public class Startup
    {

        private class CustomTransformer : HttpTransformer
        {
            public override async ValueTask TransformRequestAsync(HttpContext httpContext,
                HttpRequestMessage proxyRequest, string destinationPrefix, CancellationToken cancellationToken)
            {
                // Copy all request headers
                await base.TransformRequestAsync(httpContext, proxyRequest, destinationPrefix, cancellationToken);

                // Customize the query string:
                var queryContext = new QueryTransformContext(httpContext.Request);

                // Assign the custom uri. Be careful about extra slashes when concatenating here. RequestUtilities.MakeDestinationAddress is a safe default.
                proxyRequest.RequestUri = RequestUtilities.MakeDestinationAddress("https://maps.googleapis.com/maps/api", httpContext.Request.Path, queryContext.QueryString);

                // Suppress the original request header, use the one from the destination Uri.
                proxyRequest.Headers.Host = null;
            }
        }

        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            Configuration = configuration;
            Env = env;
        }

        public IConfiguration Configuration { get; }

        public IWebHostEnvironment Env { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services
            .AddDbContext<VepoContext>(opt =>
            {
                opt
                .UseNpgsql(
                    Configuration
                    .GetConnectionString("DefaultConnection"),
                         o => o.UseNetTopologySuite()
                    )
                    .EnableSensitiveDataLogging()
                    .EnableDetailedErrors()
                    .LogTo(Console.WriteLine);
            });

            services.AddHttpContextAccessor();

            services.AddHttpForwarder();

            services.AddTransient<UserResolverService>();

            services.AddTransient<ExtendedVepoContext>();

            services.AddControllers().AddJsonOptions(opt =>
            {
                opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
                opt.JsonSerializerOptions.Converters.Add(new GeoJsonConverterFactory());
            });

            services.AddControllers(config =>
            {
                var policy = new AuthorizationPolicyBuilder()
                                .RequireAuthenticatedUser()
                                .Build();
                config.Filters.Add(new AuthorizeFilter(policy));

            }).AddNewtonsoftJson(x =>
            {
                x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
                x.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
            }).AddJsonOptions(opt =>
            {
                opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
            });


            if (Env.IsDevelopment())
            {
                FirebaseApp.Create(new AppOptions()
                {
                    Credential = GoogleCredential.FromFile("firebase_admin_sdk_development.json"),
                },
                "vepo-dev-e5b8a"
                );
            }


            if (Env.IsQa())
            {
                FirebaseApp.Create(new AppOptions()
                {
                    Credential = GoogleCredential.FromFile("firebase_admin_sdk_qa.json"),
                },
                "vepo-qa");
            }


            var claims = new Dictionary<string, object>
            {
                { ClaimTypes.Role, "User" }
            };

            services.AddCors(options =>
            {
                options.AddPolicy("AllowAll", builder =>
                {
                    builder
                    .AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowAnyHeader();
                });
            });

            services
                .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        options.Authority = Configuration["FirebaseAuthority"];
                        options.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidateIssuer = true,
                            ValidIssuer = Configuration["FirebaseAuthority"],
                            ValidateAudience = true,
                            ValidAudience = Configuration["FirebaseProjectId"],
                            ValidateLifetime = true
                        };
                    });

            services.AddMvc().AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
            });

            services.AddScoped(typeof(IGroceryItmEstsRepository), typeof(GroceryItmEstsRepository));
            services.AddScoped(typeof(IAllVgnItmEstsRepository), typeof(AllVgnItmEstsRepository));
            services.AddScoped(typeof(IEventItmEstsRepository), typeof(EventItmEstsRepository));
            services.AddScoped(typeof(IFashionItmEstsRepository), typeof(FashionItmEstsRepository));
            services.AddScoped(typeof(IRecipeItmEstsRepository), typeof(RecipeItmEstsRepository));
            services.AddScoped(typeof(IGroceryStoreItmEstsRepository), typeof(GroceryStoreItmEstsRepository));
            services.AddScoped(typeof(IRestaurantItmEstsRepository), typeof(RestaurantItmEstsRepository));
            services.AddScoped(typeof(IUsersRepository), typeof(UsersRepository));
            services.AddScoped(typeof(IBookMarksRepository), typeof(BookMarksRepository));
            services.AddScoped(typeof(IGroceryItmsRepository), typeof(GroceryItmsRepository));
            services.AddScoped(typeof(IEventItmsRepository), typeof(EventItmsRepository));
            services.AddScoped(typeof(IFashionItmsRepository), typeof(FashionItmsRepository));
            services.AddScoped(typeof(IRecipeItmsRepository), typeof(RecipeItmsRepository));
            services.AddScoped(typeof(IGroceryStoreItmsRepository), typeof(GroceryStoreItmsRepository));
            services.AddScoped(typeof(IRestaurantItmsRepository), typeof(RestaurantItmsRepository));
            services.AddScoped(typeof(IMenuItmsRepository), typeof(MenuItmsRepository));
            services.AddScoped<IUsersService, UsersService>();
            services.AddScoped<IBookMarksService, BookMarksService>();
            services.AddScoped<IMenuItmEstsService, MenuItmEstsService>();
            services.AddScoped<IGroceryStoreItmEstsService, GroceryStoreItmEstsService>();
            services.AddScoped<IRestaurantItmEstsService, RestaurantItmEstsService>();
            services.AddScoped<IEventItmEstsService, EventItmEstsService>();
            services.AddScoped<IFashionItmEstsService, FashionItmEstsService>();
            services.AddScoped<IRecipeItmEstsService, RecipeItmEstsService>();
            services.AddScoped<IGroceryItmEstsService, GroceryItmEstsService>();
            services.AddScoped<IAllVgnItmEstsService, AllVgnItmEstsService>();
            services.AddScoped<IMenuItmsService, MenuItmsService>();
            services.AddScoped<IGroceryStoreItmsService, GroceryStoreItmsService>();
            services.AddScoped<IRestaurantItmsService, RestaurantItmsService>();
            services.AddScoped<IEventItmsService, EventItmsService>();
            services.AddScoped<IFashionItmsService, FashionItmsService>();
            services.AddScoped<IRecipeItmsService, RecipeItmsService>();
            services.AddScoped<IGroceryItmsService, GroceryItmsService>();

            services.AddScoped(typeof(IMenuItmEstsRepository), typeof(MenuItmEstsRepository));

            services.AddScoped<ISearchService, SearchService>(serviceProvider =>
            {
                return new SearchService(
                        Configuration["openSearchEndpoint"],
                        Configuration["openSearchUsername"],
                        Configuration["openSearchPassword"],
                        Configuration["openSearchIndexName"]);
            });

            var x = Configuration["openSearchEndpoint"];

            services.AddScoped<IGroceryItmsSearchIndexService, GroceryItmsSearchIndexService>();
            services.AddScoped<IRecipeItmsSearchIndexService, RecipeItmsSearchIndexService>();
            services.AddScoped<IEventItmsSearchIndexService, EventItmsSearchIndexService>();
            services.AddScoped<IFashionItmsSearchIndexService, FashionItmsSearchIndexService>();
            services.AddScoped<IMenuItmsSearchIndexService, MenuItmsSearchIndexService>();
            services.AddScoped<IRestaurantItmsSearchIndexService, RestaurantItmsSearchIndexService>();
            services.AddScoped<IGroceryStoreItmsSearchIndexService, GroceryStoreItmsSearchIndexService>();
            services.AddScoped<IAllVgnItmsSearchIndexService, AllVgnItmsSearchIndexService>();

            services.AddAutoMapper(
                typeof(EstProfile),
                typeof(VgnItmEstProfile),
                typeof(VgnItmProfile),
                typeof(EventItmEstProfile),
                typeof(EventItmProfile),
                typeof(FashionItmEstProfile),
                typeof(FashionItmProfile),
                typeof(RecipeItmEstProfile),
                typeof(RecipeItmProfile),
                typeof(GroceryItmEstProfile),
                typeof(GroceryItmProfile),
                typeof(GroceryStoreItmEstProfile),
                typeof(GroceryStoreItmProfile),
                typeof(RestaurantItmEstProfile),
                typeof(RestaurantItmProfile),
                typeof(MenuItmEstProfile),
                typeof(MenuItmProfile));

            services.AddSwaggerGen();
        }

        [Obsolete]
        public void Configure(
            IApplicationBuilder app,
            IWebHostEnvironment env,
            VepoContext context,
            IGroceryItmsSearchIndexService searchIndexService,
            IHttpForwarder forwarder//,
            /*ILogger logger*/)
        {



            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // app.UseCors(options =>
            // {
            //     options.SetIsOriginAllowedToAllowWildcardSubdomains()
            //         .AllowAnyHeader()
            //         .AllowAnyMethod()
            //         .AllowCredentials()
            //         .Build();
            // }).Build();

            app.UseCors(b => b.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());

            app.UseHttpsRedirection();
            app.UseRouting();

            NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite();
            app.UseAuthentication();
            app.UseAuthorization();

            var httpClient = new HttpMessageInvoker(new SocketsHttpHandler()
            {
                UseProxy = false,
                AllowAutoRedirect = false,
                AutomaticDecompression = DecompressionMethods.None,
                UseCookies = false,
                ActivityHeadersPropagator = new ReverseProxyPropagator(DistributedContextPropagator.Current),
                ConnectTimeout = TimeSpan.FromSeconds(15),
            });
            var transformer = new CustomTransformer(); // or HttpTransformer.Default;
            var requestConfig = new ForwarderRequestConfig { ActivityTimeout = TimeSpan.FromSeconds(100) };

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers().RequireCors("AllowAll"); ;

                RequestDelegate googleMapsApi = async httpContext =>
                {
                    var error = await forwarder.SendAsync(httpContext, "https://maps.googleapis.com/maps/api/",
                    httpClient, requestConfig, transformer);
                    // Check if the operation was successful
                    if (error != ForwarderError.None)
                    {
                        var errorFeature = httpContext.GetForwarderErrorFeature();
                        var exception = errorFeature.Exception;
                    }
                };

                endpoints.Map("/place/{**catch-all}", googleMapsApi);
                endpoints.Map("/geocode/{**catch-all}", googleMapsApi);
            });

            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My Test1 Api v1");
            });

            searchIndexService.ReIndex(context, SearchIndexes.All);
        }
    }

    public static class HostEnvironmentExtensions
    {
        public static bool IsQa(this IHostEnvironment hostingEnvironment)
        {
            return hostingEnvironment.IsEnvironment("Qa");
        }
    }
}

BTW it is hosted on AWS Elastic Beanstalk, on a Linux box, and it was when it was not using ssl too, and it only required that app.useCors() one liner back then to fix all CORS issues.

BeniaminoBaggins
  • 11,202
  • 41
  • 152
  • 287

0 Answers0