WebAPI CORS and static files - c#

I have a WebApi, it is CORS enabled and works nicely.
I want to add static files which are served up by the API to be supplementary to the actual WebAPI methods.
The static files are served up just fine if you go to them directly, however if I try and ajax them in on another domain I get CORS issues.
The actual file in question is a static .html file.
I really don't want to create a wrapper controller to serve up static files as it opens a bunch of security concerns if I do it dynamically.
I am currently doing CORS with a custom DelegatingHandler (not the WebAPI2 builtin way) but this handler is not getting called for static files.
How can I intercept static file requests in WebAPI and apply the relevent CORS headers where applicable?

Using Marcus solution, I got my net core server working with cors, also for static files, complete code of startup.cs:
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using NotariasWebsDominio.Configuracion;
using System.IO;
namespace NotariasWebs
{
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)
{
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
#if DEBUG
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("*",
"http://localhost:8081");
});
});
#endif
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// global cors policy
app.UseCors(x => x
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
if (!string.IsNullOrEmpty(ConfiguracionDominio.RutaDatos))
{
if (!Directory.Exists(ConfiguracionDominio.RutaDatos)) Directory.CreateDirectory(ConfiguracionDominio.RutaDatos);
app.UseFileServer(new FileServerOptions() { FileProvider = new PhysicalFileProvider(ConfiguracionDominio.RutaDatos), RequestPath = "/appdata",
StaticFileOptions = { OnPrepareResponse = AddCorsHeader }, });
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
private static void AddCorsHeader(StaticFileResponseContext obj)
{
obj.Context.Response.Headers["Access-Control-Allow-Origin"] = "*";
}
}
}

Assuming you're using IAppBuilder.UseFileServer(...) with FileServerOptions to serve your static files, you can add the CORS headers there.
var options = new FileServerOptions
{
...
StaticFileOptions =
{
OnPrepareResponse = AddCorsHeader
},
...
};
And your handler can just be (for example):
private static void AddCorsHeader(StaticFileResponseContext obj)
{
obj.OwinContext.Response.Headers["Access-Control-Allow-Origin"] = "*";
}
It's pretty broad but works just fine for me.

Related

HTTP Error 404 when trying to access endpoint of ASP.NET core Web API

I've created a new ASP.NET core Web API project. But when I run it in my development environment it is giving me "HTTP Error 404. This localhost page can't be found.". I tried debugging the application by placing several debug points in Program.cs and ServiceExtension.cs class, but the program control doesn't seem to enter the Controller classes and Service classes.
My program.cs is as below:
var builder = WebApplication.CreateBuilder(args);
// Including the path for configuration file for the NLog configuration.
LogManager.LoadConfiguration(string.Concat(Directory.GetCurrentDirectory(), "/nlog.config"));
// Add services to the container.
builder.Services.ConfigureCors();
builder.Services.ConfigureIISIntegration();
builder.Services.ConfigureLoggerService();
builder.Services.ConfigureSqlContext(builder.Configuration);
builder.Services.ConfigureRepositoryManager();
builder.Services.ConfigureServiceManager();
builder.Services.AddControllers().AddApplicationPart(typeof(CompanyEmployees.Presentation.AssemblyReference).Assembly);
var app = builder.Build();
if(app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All });
app.UseCors("CorsPolicy");
app.UseAuthorization();
app.MapControllers();
app.Run();
The ServiceExtension.cs class is below:
namespace CompanyEmployees.Extensions
{
public static class ServiceExtensions
{
public static void ConfigureCors(this IServiceCollection services) =>
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});
public static void ConfigureIISIntegration(this IServiceCollection services) =>
services.Configure<IISOptions>(options =>
{
//We are not adding any options becasue we are configuring for default ones
});
public static void ConfigureLoggerService(this IServiceCollection services) => services.AddSingleton<ILoggerManager, LoggerManager>();
public static void ConfigureRepositoryManager(this IServiceCollection services) => services.AddScoped<IRepositoryManager, RepositoryManager>();
public static void ConfigureServiceManager(this IServiceCollection services) => services.AddScoped<IServiceManager, ServiceManager>();
public static void ConfigureSqlContext(this IServiceCollection services, IConfiguration configuration) => services.AddDbContext<RepositoryContext>(opts => opts.UseSqlServer(configuration.GetConnectionString("sqlconnection")));
}
}
The only controller class is as below:
namespace CompanyEmployees.Presentation.Controllers
{
[Route("api/companies")]
[ApiController]
public class CompaniesController : ControllerBase
{
private readonly IServiceManager _serviceManager;
public CompaniesController(IServiceManager serviceManager)
{
_serviceManager = serviceManager;
}
[HttpGet]
public IActionResult GetCompanies()
{
try
{
var companies = _serviceManager.CompanyService.GetAllCompanies(trackChanges: false);
return Ok(companies);
}
catch
{
return StatusCode(500, "Internal Server Error");
}
}
}
}
Does anyone know what is going wrong here? or how can I effectively debug the solution?
you have decorated you controller with
[Route("api/companies")]
but in your call you are not including "api".
just call
localhost:5000/api/companies

I'm getting CORS error with CORS configured on ASP.NET Core Web API app

I have an ASP.NET Core Web API hosted in Azure. When I'm trying to make a fetch request from my web app hosted on Vercell, I'm getting this error:
Access to fetch at {myapi enpoint} from origin 'https://{myapp}.vercel.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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
This is my Startup.cs file:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Cors;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using Pomelo.EntityFrameworkCore.MySql;
using System.Threading.Tasks;
using ctsapi.Services;
using Jose;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using ctsapi.Models;
using Newtonsoft.Json.Linq;
using Microsoft.AspNetCore.Http;
using System.Net;
namespace ctsapi
{
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.AddCors(options =>
{
options.AddPolicy("AllowAllOrigins", builder =>
{
builder.AllowAnyOrigin();
builder.AllowAnyMethod();
builder.AllowAnyHeader();
});
});
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "ctsapi", Version = "v1" });
//c.IncludeXmlComments(XmlCommentsPath.XmlCommentsFilePath);
});
var jwtSection = Configuration.GetSection("JWTSettings");
services.Configure<JWTSettings>(jwtSection);
//to validate the token which has been sent by clients
var appSettings = jwtSection.Get<JWTSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.SecretKey);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = true;
x.SaveToken = true;
x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddAuthorization(options =>
{
options.AddPolicy(Policies.Admin, Policies.AdminPolicy());
options.AddPolicy(Policies.ShopKeeper, Policies.ShopKeeperPolicy());
options.AddPolicy(Policies.User, Policies.UserPolicy());
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseDefaultFiles();
app.UseStaticFiles(); // dodanie wwwroot
//if (env.IsDevelopment())
//{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ctsapi v1"));
//}
app.UseHttpsRedirection();
app.UseRouting();
app.Use(async (context, next) =>
{
await next();
if (context.Response.StatusCode == (int)HttpStatusCode.Unauthorized)
{
// "Token Validation Has Failed. Request Access Denied"
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(new ErrorDto()
{
StatusCode = 401,
Message = "Token Validation Has Failed. Request Access Denied"
}.ToString());
}
});
app.UseCors("AllowAllOrigins");
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
Any idea why this is happening?
My web app framework is Next.js.
This is my Azure configuration:
Default deploy profile (WebApp hosted on Windows machine with F1 tier)
I even changed the web.config file to always send required headers
Try to use this syntax
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("AllowAnyOrigin",
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
.....
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
.....
// app.UseRouting();
app.UseCors("AllowAnyOrigin");
// app.UseAuthorization();
// app.UseEndpoints(..
}
Make sure that UseCors should be in the end of Configure method but before UseAuthorizaton. AddCors should be at the top of Configure services.
So it looks like the Framework on Backend side just have some problems (I don't know how to describe it). When I restarted my PC and then rebuild my App, everything works fine.
Thanks everyone for every comment 💗

Fetching swagger-ui returns 404 in a ASP.NET Core 3.1 app in Azure

When loading the /swagger/index.html page the browser can't find the swagger-ui resources required when deployed to an App Servicce in Azure, returning 404. It works when running locally. My setup is:
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Nexus WebApp",
Version = "v1"
});
options.CustomSchemaIds(type => type.ToString());
});
var builder = endpoints.CreateApplicationBuilder();
builder.UseSwagger();
builder.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Nexus WebApp");
});
var pipeline = builder.Build();
endpoints.Map("/swagger", pipeline)
.RequireAuthorization(new AuthorizeAttribute());
endpoints.Map("/swagger/index.html", pipeline)
.RequireAuthorization(new AuthorizeAttribute());
endpoints.Map("/swagger/{documentName}/swagger.json", pipeline)
.RequireAuthorization(new AuthorizeAttribute());
I've tried with a relative path fro the swagger endpoint like so ..\swagger\v1/swagger.json, I've tried specifying a RoutePrefix all to no avail unfortunately. I'm aware similar questions have been asked but unfortunately none seem to help.
Does anyone have any clues?
Update
These are the resources it is returning 404 for:
https://{domain}/swagger/swagger-ui.css
https://{domain}/swagger/swagger-ui-standalone-preset.js
https://{domain}/swagger/swagger-ui-bundle.js
I suspect, your implementation is wrong. Here is the complete Startup code for setting up Swagger UI in NET Core:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Swagger;
namespace IDGSwaggerDemo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion
(CompatibilityVersion.Version_2_2);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "Swagger Demo",
Description = "Swagger Demo for ValuesController",
TermsOfService = "None",
Contact = new Contact() { Name = "Joydip Kanjilal",
Email = "joydipkanjilal#yahoo.com",
Url = "www.google.com"
}
});
});
}
public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
});
}
}
}
Check out this tutorial for more enhanced Swagger implementation.
Finally, after struggling with this for hours, I managed to get it to work. Note that I have the special requirement that I have a Web API for which I want controllers to use Bearer token authentication, and at the same time I want the Swagger UI to be protected by OIDC.
I have left out parts in the class that are not relevant for this answer.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMvc();
// Add authentication to web API
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration);
// Add authentication to web app for Swagger authorization
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration);
builder.Services.AddSwaggerGen();
builder.Services.AddAuthorization(options =>
{
options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build();
});
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.Use(async (context, next) =>
{
if (context.Request.Path.StartsWithSegments("/swagger") && context.User.Identity?.IsAuthenticated == false)
{
await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme);
}
else
{
await next();
}
});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API v1");
});
app.MapControllers();
app.Run();

How to set ASP.NET CORS OPTION to allow application/json

As shown on the code below, I am sending a post request to a web api created using ASP.NET. The server is an ISS Express.
The error the browser is sending to me is
MainPage.html:1 Access to fetch at 'https://localhost:44346/api/topic' from origin 'null' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response
I have looked at several articles and have found that my issue is that the CORS option in my WEB-API doesn't send back an option that says to allow application/json. From what I understand, the reason this issue is occurring is because my browser and ISS Express are on the same machine so CORS is being triggered. I have looked for resources to help me get the CORS in ASP.NET to include the application/json as an allowed header and have made no headway at all. I also tried disabling the CORS in my browser but I couldn't find an web page that explained how to do it either.
What do I need to do to fix this issue?
JavaScript Code
function SubmitTopic()
{
//Boilerplate code erased for succinctness
console.log("Creating Request")
const request = new Request("https://localhost:44346/api/topic", {
method: 'POST',
body: json,
headers: {
'Content-Type': 'application/json'
}
});
console.log(request)
console.log("Starting POST request to API")
fetch(request).then(res => {
if (res.status == 201) {
console.log("Successfully added json")
console.log("Clearing name and description boxes")
name.value = "";
description.value = "";
}
else {
console.error("A problem has occured")
alert("Failed to post")
}
})
}
C# - Startup Code
using DSPWHU.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Cors;
namespace DSPWHU
{
public class Startup
{
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
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.AddDbContext<EvidenceContext>(opt => opt.UseSqlite("EvidenceList"));
services.AddDbContext<TopicContext>(opt => opt.UseSqlite("TopicList"));
services.AddControllers();
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.AllowAnyOrigin();
});
});
}
// 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.UseHttpsRedirection();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
Try to replace your service.AddCors() with this:
services.AddCors(o => o.AddPolicy(MyAllowSpecificOrigins, builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
and place it at the top of ConfigureServices section.

Getting The page was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint '.well-known/openid-configuration'

So I have an ASP.Net Core Hosted Blazor Web Assembly project using Identity Server 4 to manage my logins and registration and when I am debugging and I try to log into my app, the endpoint '.well-known/openid-configuration' is served over HTTPS but when I run the published version of it in Docker it is served over HTTP and causing my login page not to work. How can I get it to be served over HTTPS?
The full error is: AuthenticationService.js:1 Mixed Content: The page at 'https://musicfusion.app/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://musicfusion.app/.well-known/openid-configuration'. This request has been blocked; the content must be served over HTTPS.
Edit: My Startup.cs
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Linq;
using Soundbox.Server.Data;
using Soundbox.Shared;
using System;
using Blazored.Toast;
using test.Server.Hubs;
using Microsoft.AspNetCore.Identity.UI.Services;
using test.Server.Services;
using Microsoft.AspNetCore.HttpOverrides;
namespace test.Server
{
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.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite("Data Source=/data/test.db"));
services.AddBlazoredToast();
services.Configure<APIKeys>(this.Configuration.GetSection("APIKeys"));
services.Configure<AuthMessageSenderOptions>(this.Configuration.GetSection("Emails"));
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
//services.AddCors(options =>
//{
// options.AddPolicy("AllowSpecificOrigin",
// builder =>
// {
// builder
// .AllowAnyOrigin()
// .AllowAnyMethod()
// .AllowAnyHeader();
// });
//});
services.AddControllersWithViews();
// requires
// using Microsoft.AspNetCore.Identity.UI.Services;
// using WebPWrecover.Services;
services.AddTransient<IEmailSender, EmailSender>();
services.AddRazorPages();
services.AddSignalR();
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCompression();
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.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
//app.UseCors("AllowSpecificOrigin");
app.UseRouting();
app.UseIdentityServer();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapHub<PlaylistHub>("/playlisthub");
endpoints.MapFallbackToFile("index.html");
});
UpdateDatabase(app);
}
private static void UpdateDatabase(IApplicationBuilder app)
{
using (var serviceScope = app.ApplicationServices
.GetRequiredService<IServiceScopeFactory>()
.CreateScope())
{
using (var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>())
{
context.Database.Migrate();
}
}
}
}
}
#Carl and #Jared are correct but simply forcing HTTPS won't work if you are behind a load balancer or something similar.
https://leastprivilege.com/2017/10/09/new-in-identityserver4-v2-simplified-configuration-behind-load-balancers-or-reverse-proxies/
Example request via https that serves endpoint links in http from app hosted in GCP Cloud Run. Exact same code served https endpoints in Azure and IIS.
Recommended approach is using PublicOrigin in IdentityServer4:
app.Use(async (ctx, next) =>
{
ctx.SetIdentityServerOrigin("https://example.com");
await next();
});
or
app.Use(async (ctx, next) =>
{
ctx.Request.Scheme = "https";
ctx.Request.Host = new HostString("example.com");
await next();
});
https://github.com/IdentityServer/IdentityServer4/issues/4535#issuecomment-647084412
Adding the following line to startup.cs in the server project seems to have fixed the issue for me:
app.Use((ctx, next) => { ctx.SetIdentityServerOrigin("https://www.my-domain-name-here.co.uk"); return next(); });
I was struggling with this too. Finally came up with a solution. In Startup.ConfigureServices, add the IdentityServer options like this:
services.AddIdentityServer(options =>
{
options.PublicOrigin = Configuration["PublicOrigin"];
})
Then put the public HTTPS origin in your appsettings.json (e.g. "PublicOrigin": "https://example.com").
If you are using IdentityServer4 then you can put this in your startup:
app.Use(async (ctx, next) =>
{
ctx.Request.Scheme = "https";
await next();
});
It will then make Identity Server use https for all links that it creates. This helped a lot as I'm using a reverse proxy
The solution to this was to have Cloudflare force all traffic to be HTTPS.
Edit: to get it right, follow this tutorial: https://blog.cloudflare.com/how-to-make-your-site-https-only/

Categories

Resources