A
A
Anton2020-11-20 20:23:55
IIS
Anton, 2020-11-20 20:23:55

How to set up CORS for React for requests to other domain's API?

There are the following components.
1. IIS without client authentication, which gives the SPA application.
2. SPA written in React with axios on board.
3. 2 more IIS with domain authorization via Kerberos, which serve as proxy servers to several REST APIs written in Node.

The problem is this: as soon as we go to the first IIS, it gives us SPA. It loads successfully, and then knocks on the APIs that are behind the IIS proxy, and then an error immediately occurs. IIS requires authorization, and the browser does not want to respond to the request and just gets a 401 error.

All IISs have the following headers enabled:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true

In the axios settings in the SPA, the same thing, but the authorization request still does not occur.
Tell me what they all lack?

In Access-Control-Allow-Origin I tried to slip both IIS addresses one at a time and an array of all at once, to no avail.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladimir Korotenko, 2020-11-20
@zakharoffam

This is not a node, just check the headers for a match

using Microsoft.AspNetCore.ApiAuthorization.IdentityServer;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.SpaServices;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using TwoRecycle.Code;
using TwoRecycle.Data;
using TwoRecycle.Model;
using VueCliMiddleware;

namespace TwoRecycle
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddDefaultUI()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddIdentityServer()
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>();

            services.AddAuthentication()
                .AddIdentityServerJwt();
            services.Configure<JwtBearerOptions>(
                IdentityServerJwtConstants.IdentityServerJwtBearerScheme,
                options =>
                {
                    var onTokenValidated = options.Events.OnTokenValidated;
                    options.Events.OnTokenValidated = async context => { await onTokenValidated(context); };
                });


            services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>,
                AdditionalUserClaimsPrincipalFactory>();

            services.Configure<IdentityOptions>(options =>
            {
                // Password settings.
                options.Password.RequireDigit = true;
                options.Password.RequireLowercase = true;
                options.Password.RequireNonAlphanumeric = true;
                options.Password.RequireUppercase = true;
                options.Password.RequiredLength = 6;
                options.Password.RequiredUniqueChars = 1;

                // Lockout settings.
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                options.Lockout.MaxFailedAccessAttempts = 5;
                options.Lockout.AllowedForNewUsers = true;

                // User settings.
                options.User.AllowedUserNameCharacters =
                    "ab[email protected]+";
                options.User.RequireUniqueEmail = false;
            });

            services.ConfigureApplicationCookie(options =>
            {
                // Cookie settings
                options.Cookie.HttpOnly = true;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
                options.LoginPath = "/Identity/Account/Login";
                options.AccessDeniedPath = "/Identity/Account/AccessDenied";
                options.SlidingExpiration = true;
            });
            services.AddControllersWithViews();
            services.AddRazorPages();
            // NOTE: PRODUCTION Ensure this is the same path that is specified in your webpack output
            services.AddSpaStaticFiles(opt => opt.RootPath = "wwwroot");
            services.AddAuthorization(config =>
            {
                config.AddPolicy("IsAdmin", policy => policy.RequireClaim("IsAdmin", "true"));
            });
            services.AddCors(options =>
            {
                // this defines a CORS policy called "default"
                options.AddPolicy("default", policy =>
                {
                    policy.WithOrigins("https://localhost:44343", "https://www.2recycle.ru")
                        .AllowAnyHeader()
                        .AllowAnyMethod();
                });
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();
            app.UseCors("default");
            app.UseAuthentication();
            app.UseIdentityServer();
            app.UseAuthorization();


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

                endpoints.MapRazorPages();
                //todo: client from here https://github.com/joaojosefilho/vuejsOidcClient

                // NOTE: VueCliProxy is meant for developement and hot module reload
                // NOTE: SSR has not been tested
                // Production systems should only need the UseSpaStaticFiles() (above)
                // You could wrap this proxy in either
                // if (System.Diagnostics.Debugger.IsAttached)
                // or a preprocessor such as #if DEBUG
                endpoints.MapToVueCliProxy(
                    "{*path}",
                    new SpaOptions { SourcePath = "../vue-app" },
                    npmScript: (System.Diagnostics.Debugger.IsAttached) ? "serve" : null,
                    regex: "Compiled successfully",
                    forceKill: true
                );

            });
        }
    }
}

Request URL: https://localhost:44343/Identity/Account/Login
Request Method: POST
Status Code: 302 
Remote Address: [::1]:44343
Referrer Policy: strict-origin-when-cross-origin
access-control-allow-origin: https://localhost:44343
cache-control: no-cache
date: Fri, 20 Nov 2020 18:08:42 GMT
expires: Thu, 01 Jan 1970 00:00:00 GMT
location: /
pragma: no-cache
server: Microsoft-IIS/10.0
set-cookie: idsrv.session=awkFp-5bzZoUGr5YmW0ILw; path=/; secure; samesite=none
set-cookie: .AspNetCore.Identity.Application=CfDJ8HSLnn4dT-FDg-hkyrBA0cj1cM6qHlOijWSDj9T492YPP264RtbSYW_KCJu603bg-uXJ6sOTX2apHtiQSSF4zgjcsHmLkOWOQYHiaOBfHCJhefscm4tvrtp8Y1fvzBzdj_NFv8MGvhGPDRkwPaQioPCMoxEAescm_wVdsd9q-OLMu-2SFCoauRGyp4m-94ljj0hqWemXD5SRw3U-XH5-ZihjLYRJxb0VI-Ih2CQAGsslCk0M7CfP9Dfvlnj_xtIXzyi2cdfFOxxCRzJ_HAfV9t9cFVPKdkPj58ZEQwDPysV66UPPAk04rPoBxihwTKshdhGcrGXvennVqcSwf4kyIWtNUMgXes0eaFmRueWuUbNNfhgCVfAC5fe6FE4MEvFoqVpjUz3K0rGNV2qMcLlAtfRPNhF2QOEBGD5NnHwgQwziNOo4fvv5mybNHuEsVDMt7xDX2agjk_Lr34kAYbJxfusKx0amxqAnhvIIaMlLruz5HMZOLNfReqUsqhclgJM2Nq2AD57rfurp41qJAGZftS37BAhSjci24WsD5X5m_TQ6qGh74CbyUY4gc6kMmqQbE6GrPyVCOdV_E7eCj8q7ZzUCyM3Z8k1xSx8Sn4KXR8J8DyVLM9HBNEMtMFaaIWBqI2oy8JhUaFbybeQa29u92GRiqFR7a81mS9bpxqDOvXC81IduLWXZyzyJOxuFhm75Ju19MorwmpFQOkLvlJUvr_rtUbXhwd0rXjjlGqAMULEP; path=/; secure; samesite=none; httponly
set-cookie: .AspNetCore.Mvc.CookieTempDataProvider=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; samesite=lax; httponly
vary: Origin
x-powered-by: ASP.NET
:authority: localhost:44343
:method: POST
:path: /Identity/Account/Login
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
accept-encoding: gzip, deflate, br
accept-language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
cache-control: max-age=0
content-length: 266
content-type: application/x-www-form-urlencoded
cookie: .AspNetCore.Antiforgery.iEjq0RT987g=CfDJ8HSLnn4dT-FDg-hkyrBA0cjZI81abO-Klbwxcr-ZyIP1PHoFGyW39AWpPtmqiN0l706JrI9q7KPxvY97x4svXztoLzWo4qnySppUyB_GhDzeaOR3JQtYkRypJqWRAZfew8j2sqclVovCDkHAKhy5jlw
origin: https://localhost:44343
referer: https://localhost:44343/Identity/Account/Login
sec-fetch-dest: document
sec-fetch-mode: navigate
sec-fetch-site: same-origin
sec-fetch-user: ?1
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36
Input.Email: [email protected]
Input.Password: 123
__RequestVerificationToken: CfDJ8HSLnn4dT-FDg-hkyrBA0cgTfwl1CtddD8AXkFr6sBqM25xP7qXeMJSe3TsUYICrsNUfzBhTEfuJ1wZjm3AbkVNAxbNUQ-57vnCKLCYLjgWKvjKO01fiXeMUVTjzwZIXwV4ktwvALnF2I2-pchmT6UU
Input.RememberMe: false

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question