Publishing web api with swagger on IIS - c#

I am trying figure out how to publish a .net core 3 API with Swagger (SwashBuckle) after following this example documentation . So it works locally and when I hit F5 IIS Express launches the site under http://localhost:8033/index.html
Here is the Configure code in startup.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(env.ContentRootPath),
RequestPath = new PathString("")
});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
c.DocumentTitle = "TestAPI";
c.DocExpansion(DocExpansion.None);
c.RoutePrefix = string.Empty;
});
}
Next I published the API to a local folder and copied the files to the IIS folder on the server. If I open the server API domain I get a page can’t be found. Which address should I use to open up the swagger UI on the server? Is something missing from the configuration?

There is no problem with your Swagger settings. Please don’t forget configure the Swagger generator, as well as the comments path for the Swagger JSON.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "ToDo API",
Description = "A simple example ASP.NET Core Web API",
TermsOfService = new Uri("https://example.com/terms"),
Contact = new OpenApiContact
{
Name = "Shayne Boyer",
Email = string.Empty,
Url = new Uri("https://twitter.com/spboyer"),
},
License = new OpenApiLicense
{
Name = "Use under LICX",
Url = new Uri("https://example.com/license"),
}
});
// Set the comments path for the Swagger JSON and UI.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
}
Besides, Please ensure that the server has installed the Asp.net core hosting bundle on the sever-side.
https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-aspnetcore-3.1.6-windows-hosting-bundle-installer
Feel free to let me know if there is anything I can help with.

Assuming we're using ASP.NET Core / 7 for building the web api.
For .NET 7 (or minimal api) we need to try commenting / adjusting the snippet below in Program.cs
// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
//{
app.UseSwagger();
app.UseSwaggerUI();
//}
Next build / publish using VS / VS Code
And access your API on local dev / test:
https://local-api.{yur-api-name}.com/{service-name}Services/swagger/index.html

Just to add, it could also be possible that the following nodes are missing from the API project file under the PropertyGroup node.
<RuntimeIdentifiers>win10-x64;</RuntimeIdentifiers>
<AspNetCoreModuleName>AspNetCoreModuleV2</AspNetCoreModuleName>

Edit your Startup.cs File
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
if (env.IsProduction() || env.IsStaging())
{
app.UseExceptionHandler("/Error/index.html");
}
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger(c =>
{
c.RouteTemplate = "swagger/{documentName}/swagger.json";
});
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "swagger";
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1");
// custom CSS
c.InjectStylesheet("/swagger-ui/custom.css");
});
app.Use(async (ctx, next) =>
{
await next();
if (ctx.Response.StatusCode == 204)
{
ctx.Response.ContentLength = 0;
}
});
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseCors();
}
https://youtu.be/6HiaXCAlRr0

Related

Dynamically setting the SPA source path in .Net Core 3.1

I have a .Net Core 3.1 application that I use as an API but it also serves my SPA (Angular). As of recently I am having some issues with SEO so I would like to serve a static version of my Angular application when Googlebot comes around.
Is here any way to dynamically set the SPA source path?
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
});
Currently I have a small middleware file where I detect Googlebot based on the UserAgent string. Then I pass that through the request.
public async Task InvokeAsync(HttpContext context)
{
var userAgent = context.Request.Headers["User-Agent"];
context.Items["isCrawler"] = userAgent.Contains("Googlebot");
await _next(context);
}
But I cannot access the Request in the Configure() method in the Startup.cs file. Is there anyway how I can make this work? I really want to be able to dynamically set the SourcePath.
Thanks a lot!
Regards
You can try the following codes , putting the middleware in Configure()method .
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use(async (context, next) =>
{
var userAgent = context.Request.Headers["User-Agent"];
context.Items["isCrawler"] = userAgent.Contains("Googlebot");
if ((bool)context.Items["isCrawler"])
{
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
});
}
else {
//do your stufff....
}
// Call the next delegate/middleware in the pipeline
await next();
});
…}

Dotnet core 3.0 project encounter cors issue because of configuration in startup.cs for uploading file function

The frontend is react project and backend is dotnet core, they are hosted in different places, that's why I need to configure the cors in startup.cs in my dotnet project.
The problem is very weird. After configuration, there is no cors issue if I run the project in my local environment(on my: pc-frontend and backend), however, on the testing server, every request from the frontend encounter cors error. The error message from console is something like this:
Access to XMLHttpRequest at 'http://dummybackend.com' from origin 'http://dummyfrontend.com' 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.
After a whole day's research, I found the problem has someting to do with one part of the configuration, which is app.UseStaticFiles,
app.UseStaticFiles(new StaticFileOptions()
{
ServeUnknownFileTypes = true,
OnPrepareResponse = (ctx) =>
{
var policy = corsPolicyProvider.GetPolicyAsync(ctx.Context, "CorsPolicy")
.ConfigureAwait(false)
.GetAwaiter().GetResult();
var corsResult = corsService.EvaluatePolicy(ctx.Context, policy);
corsService.ApplyResult(corsResult, ctx.Context.Response);
},
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), #"Uploads")),
RequestPath = new PathString("/StaticFiles"),
});
which is the configuration for file uploading. If I comment this out, there is no cors issue on the testing server(AWS EC2), but of course, I need this for successful file submitting.
I've found one solution from this blog
https://www.bytefish.de/blog/aspnetcore_static_files_cors.html
But it doesn't work
Below is the configuration I made based on the blog.
public void ConfigureServices(IServiceCollection services)
{
// Add CORS:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", policyBuilder => policyBuilder
.WithOrigins("http://dummyfrontend.com", "http://localhost:8080")
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
SetConfigurations();
services.AddDbContext<DBContext>(options => options.UseMySql(Configuration.GetConnectionString("LocalDatabase")), ServiceLifetime.Transient);
services.AddDbContext<DBContextMail>(options => options.UseMySql(Configuration.GetConnectionString("MailDatabase")), ServiceLifetime.Transient);
services.AddControllers().AddNewtonsoftJson();
services.Configure<JWT>(Configuration.GetSection("JWT"));
services.AddScoped<IUserService, UserService>();
services.AddScoped<IAffiliateService, AffiliateService>();
services.AddScoped<ICommissionService, CommissionService>();
services.AddScoped<IReferrerProfileService, ReferrerProfileService>();
services.AddScoped<IApplicationService, ApplicationService>();
services.AddScoped<IDashboardService, DashboardService>();
services.AddScoped<ITeamService, TeamService>();
services.AddScoped<IHistoryService, HistoryService>();
services.AddScoped<IScheduleService, ScheduleService>();
services.AddScoped<ISettingService, SettingService>();
services.AddScoped<IUserRolesService, UserRolesService>();
services.AddScoped<IEmailTemplateService, EmailTemplateService>();
services.AddScoped<ISMSTemplateService, SMSTemplateService>();
services.AddScoped<IImportReferrersService, ImportReferrersService>();
if (Environment.IsDevelopment())
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1.0", new OpenApiInfo { Title = "Referrer Api v1.0", Version = "v1.0" });
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
new string[] { }
}
});
c.CustomSchemaIds(type => type.FullName);
var filePath = Path.Combine(System.AppContext.BaseDirectory, "ReferralSystem.xml");
c.IncludeXmlComments(filePath);
});
services.AddSwaggerGenNewtonsoftSupport();
}
var key = Encoding.ASCII.GetBytes(Configuration.GetSection("JWT").Get<JWT>().Secret);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.Configure<FormOptions>(o =>
{
o.ValueLengthLimit = int.MaxValue;
o.MultipartBodyLengthLimit = int.MaxValue;
o.MemoryBufferThreshold = int.MaxValue;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, ICorsService corsService, ICorsPolicyProvider corsPolicyProvider)
{
app.UseRouting();
loggerFactory.AddLog4Net();
app.UseCors("CorsPolicy");
// To serve PBF Files, we need to allow unknown filetypes
// to be served by the Webserver:
if (env.IsDevelopment())
{
app.UseHttpsRedirection();
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1.0/swagger.json", "Referrer Api V1.0");
c.DocumentTitle = "Referrer System API Document";
c.DocExpansion(DocExpansion.None);
});
}
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseStaticFiles(new StaticFileOptions()
{
ServeUnknownFileTypes = true,
OnPrepareResponse = (ctx) =>
{
var policy = corsPolicyProvider.GetPolicyAsync(ctx.Context, "CorsPolicy")
.ConfigureAwait(false)
.GetAwaiter().GetResult();
var corsResult = corsService.EvaluatePolicy(ctx.Context, policy);
corsService.ApplyResult(corsResult, ctx.Context.Response);
},
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), #"Uploads")),
RequestPath = new PathString("/StaticFiles"),
});
}
I found the solution myself, it is because inside the app.UseStaticFiles configuration, I define a folder which is #"Uploads", and after publishing the project, there is no such folder inside the publish folder, therefore, the project encounter startup exception.
The solution is simply manually add the folder in the published file folder, so that the project wont encounter startup exception.

ASP.NET CORE 3.1: Azure AD Authentication fails in EDGE. Infinite redirect loops and page reloads during authentication

I have no issues with chrome. It is the edge browser where I am facing issues. I have tried to clear the cache. Deleted cookies. Reset the browser. Nothing worked. I keep getting infinite loop on login. And it eventually fails with message "We couldn't sign you in. Please try again." . Any help is appreciated.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
});
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.Events.OnRedirectToIdentityProviderForSignOut = async context =>
{
Console.WriteLine("intercepted");
};
});
var azureAd = new AzureAd();
Configuration.GetSection("AzureAd").Bind(azureAd);
services.AddControllersWithViews();
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
var url = "https://abc.xyz.com/platform/signin-oidc";
//var url = "https://localhost:5001/platform/signin-oidc";
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
options.SaveTokens = true;
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = async context =>
{
context.ProtocolMessage.RedirectUri = url;
//context.Response.Headers.Add("Referrer-Policy", "no-referrer");
await Task.FromResult(0);
}
};
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors("CorsPolicy");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/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.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "platform",
pattern: "/platform/{controller=Home}/{action=Index}/{id?}");
});
}
EDIT
I do see this in networks tab in developer tools:
The issue was because the token sent back by the AD is stored in a cookie. And the cookie was blocked because it did not have secure attribute.
It did not have secure attribute because the application deployed on Kubernetes Cluster and the communication was http instead of https between front door and the application.
So in order to force secure cookies I had to add the following inside public void Configure(IApplicationBuilder app, IWebHostEnvironment env):
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.Use(async (context, next) =>
{
if (context.Request.Host.Host.ToLower() != "localhost")
context.Request.Scheme = "https";
await next.Invoke();
});

"There was an error trying to log you in: '' " Blazor WebAssembly using IdentiyServer Authentication

I have a Blazor WebAssembly app using IdentityServer that comes with the template as my authentication service. I am having an issue where some users are seeing "There was an error trying to log you in: ''" once they try to login. I had users clear cookies and cache, and they are still experiencing this problem in all their browsers. The weird thing is that most users are able to login, but only a small percent is getting that error. Another odd thing is that it seems like if they use another device such as a phone, another pc, or ipad it works. What could be causing this issue? I have been having trouble trying to debug this issue as I am not able to replicate it on my end and so far not seeing any logs to get any info.
This app is hosted in Google Cloud Platform using linux Docker container.
Thank you in advance
Edit: Here is my startup class
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
private const string XForwardedPathBase = "X-Forwarded-PathBase";
private const string XForwardedProto = "X-Forwarded-Proto";
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("https://www.fakedomainexample.com",
"https://fakedomainexample.com");
});
});
services.AddHttpContextAccessor();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseMySql(
Configuration.GetConnectionString("ConnectionString")));
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
// For some reason, I need to explicitly assign the IssuerUri or else site gets invalid_issuer error
services.AddIdentityServer(x => x.IssuerUri = "https://www.fakedomainexample.com").AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
options.IdentityResources["openid"].UserClaims.Add("name");
options.ApiResources.Single().UserClaims.Add("name");
options.IdentityResources["openid"].UserClaims.Add("role");
options.ApiResources.Single().UserClaims.Add("role");
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");
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 = 8;
options.Password.RequiredUniqueChars = 1;
// User settings.
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
options.User.RequireUniqueEmail = true;
options.SignIn.RequireConfirmedAccount = false;
});
// Added Cookie options below to fix an issue with login redirect in Chrome for http
// https://stackoverflow.com/questions/60757016/identity-server-4-post-login-redirect-not-working-in-chrome-only
// This one worked: https://stackoverflow.com/questions/63449387/cannot-redirect-back-to-angular-client-after-login-in-identity-server
services.ConfigureExternalCookie(option =>
{
option.LoginPath = "/Account/Login";
option.Cookie.IsEssential = true;
option.Cookie.SameSite = SameSiteMode.Lax;
});
services.ConfigureApplicationCookie(option =>
{
option.LoginPath = "/Account/Login";
option.Cookie.IsEssential = true;
option.Cookie.SameSite = SameSiteMode.Lax;
});
services.AddAuthentication()
.AddIdentityServerJwt();
services.AddControllersWithViews();
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseRewriter(new RewriteOptions()
.AddRedirectToWwwPermanent());
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseWebAssemblyDebugging();
}
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.Use((context, next) =>
{
if (context.Request.Headers.TryGetValue(XForwardedPathBase, out StringValues pathBase))
{
context.Request.PathBase = new PathString(pathBase);
}
if (context.Request.Headers.TryGetValue(XForwardedProto, out StringValues proto))
{
context.Request.Scheme = proto;
}
//context.SetIdentityServerOrigin("https://www.fakedomainexample.com");
return next();
});
app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
const string cacheMaxAge = "3600";
app.UseStaticFiles(new StaticFileOptions
{
OnPrepareResponse = ctx =>
{
ctx.Context.Response.Headers.Add("Cache-Control", $"public, max-age={cacheMaxAge}");
}
});
app.UseCookiePolicy(new CookiePolicyOptions
{
MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Lax,
});
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
}
}
We also faced this problem. The error appears if the server time does not match the client time. Experiments have shown that it is enough to have a difference of 10 minutes.
Ideally, the time on the client and server should be in sync.
We are currently asking customers to check the time on the device, but this is not a solution to the problem.
Who have this problem when publishing on IIS with a self-signed certificate, it may be caused by auth of Application Pool on read the Certificate.
For solve this problem, open certification manager, right click on the certificate, all tasks, private key manager and insert IIS group (IIS_IUSRS) for read/write permission. For test, try "Everyone".
Had this issue when using Blazor WASM hosted by ASP.NET 6 application and configured OIDC with Openiddict.
Issue was solved by remapping UserOption for OpenIddict default claims.
// Blazor WASM Program.cs
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");
// https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/standalone-with-authentication-library?view=aspnetcore-6.0&tabs=visual-studio
builder.Services.AddOidcAuthentication(options =>
{
builder.Configuration.Bind("Oidc", options.ProviderOptions);
// Set mapping for claims fixed issue
options.UserOptions.NameClaim = "name";
options.UserOptions.RoleClaim = "role";
options.UserOptions.ScopeClaim = "scope";
});
await builder.Build().RunAsync();
You need SameSite as None for OpenID Connect to work in this case. Also you need to have HTTPS.
Read more https://learn.microsoft.com/en-us/aspnet/core/security/samesite?view=aspnetcore-3.1
I believe you have to configure you Identity on appsettings.json
On dev you have
"IdentityServer": {
"Clients": {
"updown": {
"Profile": "IdentityServerSPA"
}
},
"Key": {
"Type": "Development"
}
But in production you must configure some certificates.
"Key": {
"Type": "File",
"FilePath": "path to .pfx",
"Password": "pass"
}
otherwise not recommended put the tempkey.json from obj folder
Got the same error when using Cognito UserPools with OIDC. The reason for me was, the profile checkbox was not selected in the App Client Settings.
With the version of .NET 7, to fix this error "there was an error trying to log you in 500" - you need to apply migrations and create a database - otherwise, this out-of-the-box solution won't work.

WebApi throws 403 error always even whith CORS enabled

I have a WebApi developed in .NET Core 2.0 for my backend. When I test my production build, I can't call a method from my controller, I've activated cors to allow everything just for testing purpose. When I build my WebApi for Development environment it works perfectly fine.
This is what I have in my startup class
public void ConfigureProduction(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
//var options = new RewriteOptions()
// .AddRedirectToHttps();
//app.UseRewriter(options);
app.UseDeveloperExceptionPage();
app.UseCors(builder => {
builder.AllowAnyOrigin();
builder.AllowAnyMethod();
builder.AllowAnyHeader();
});
app.UseMvc();
}
Additionally you need to allow credentials:
API
app.UseCors(builder =>
{
builder.AllowAnyOrigin();
builder.AllowAnyMethod();
builder.AllowAnyHeader();
builder.AllowCredentials(); // <-- add this line
});
Client
let requestOptions = new RequestOptions({withCredentials: true});

Categories