ASP.Net core with attribute routing on IIS Express gives 503 error when published - asp.net-core

I have a ASP.NET core MVC controller with attribute routing that works well locally ,like https://localhost:44322/adfs/account/login , however 503(Service Unavailable) error is returned when published on the IIS, also other routes without attribute routing works fine.No error logs in event viewer for the same.
[SecurityHeaders]
[Route("adfs/account")]
public class AccountController : Controller
{
[HttpGet]
[Route("Login")]
public async Task<IActionResult> Login(string returnUrl)
{//some code}
}
In Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment
env, ILoggerFactory loggerFactory)
{
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
app.Use(async (ctx, next) =>
{
ctx.Response.Headers.Add("Content-Security-Policy",
"default-src 'self' * 'unsafe-inline' 'unsafe-eval' data:");
await next();
});
app.UseIdentityServer();
app.UseMvcWithDefaultRoute();
}

Related

"Issuer name does not match authority" error when using reverse proxy in front of SSL terminating load-balancer

I am trying to deploy our data API using APIgee proxy. The data API is using .NET Core 3.0 on an IIS server on AWS EC2 instance:
When I make a call to the data API using Apigee proxy I am getting this exception on the IIS server:
Category: IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler
EventId: 0
RequestId: 80003dde-0002-fe00-b63f-84710c7967bb
RequestPath: /v0.1/wells/dpr
SpanId: |74716527-4b0a0a0f46d32af3.
TraceId: 74716527-4b0a0a0f46d32af3
ParentId:
Policy error while contacting the discovery endpoint https://example.com: Issuer name does not match authority: http://example.com
Exception:
System.InvalidOperationException: Policy error while contacting the discovery endpoint https://example.com: Issuer name does not match authority: http://example.com
at IdentityModel.AspNetCore.OAuth2Introspection.PostConfigureOAuth2IntrospectionOptions.GetIntrospectionEndpointFromDiscoveryDocument(OAuth2IntrospectionOptions options)
at IdentityModel.AspNetCore.OAuth2Introspection.PostConfigureOAuth2IntrospectionOptions.InitializeIntrospectionClient(OAuth2IntrospectionOptions options)
at IdentityModel.AspNetCore.OAuth2Introspection.OAuth2IntrospectionHandler.LoadClaimsForToken(String token)
at IdentityModel.AspNetCore.OAuth2Introspection.OAuth2IntrospectionHandler.HandleAuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
at IdentityServer4.AccessTokenValidation.IdentityServerAuthenticationHandler.HandleAuthenticateAsync()
From what I can see, the issue here is that the Loab-balancer is performing the SSL termination and making a call to the IIS server using HTTP and not HTTPS that is why the issuer name does not match. I have tried adding UseForwardedHeaders line to our .NET Core API:
public static IApplicationBuilder UseIdServer(this IApplicationBuilder app)
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseIdentityServer();
return app;
}
which is called here
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app
.UseCORS()
.UseCustomCookiePolicy(env)
.UseIdServer()
.UseRouting()
.UseAuth()
.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
However, that did not fix the issue.
Update 1:
I have also tried configuring the ForwardedHeaders like that in my startup.cs as suggested on the MS docs without success:
public void ConfigureServices(IServiceCollection services)
{
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders();
...
}
Update 2
I tried overriding the request schema to https in the Configure method in Startup.cs as suggested in MS docs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.Use((context, next) =>
{
context.Request.Scheme = "https";
return next();
});
...
}
That has resolved the issue. However, I am wondering how I can properly configure the X-Forwarded-* headers in the middleware.
Update 3
Thanks to #Chen who pointed me to resource which stated that I can configure the ForwardedHeaders in the Configure method like so
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedProto
});
...
}
Previously I tried the same but I used both ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto. For some reason, using just ForwardedHeaders.XForwardedProto resolved the issue.

CORS problem with custom controller and CustomClientStore in IdentityServer4

I want to add a custom end-point into IdentityServer4 but when I call API from another site, I have a CORS error.
I use a CustomClientStore to load my clients so i need to add CustomCorsPolicyService
Access to XMLHttpRequest at 'http://localhost:8082/embedded/log' from origin 'http://localhost:8080' 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.
In Startup, I add my CustomClientStore and CustomCorsPolicyService
public void ConfigureServices(IServiceCollection services)
{
...
CustomClientStore.Init(_Configuration);
var builder = services.AddIdentityServer()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiScopes(Config.GetApiScopes())
.AddRedirectUriValidator<MyUriValidator>();
builder.Services.AddSingleton<IUserRepository, UserRepository>();
builder.AddProfileService<CustomProfileService>();
builder.AddClientStore<CustomClientStore>();
//services.AddCors(setup => setup.AddDefaultPolicy(b => b.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
builder.AddCorsPolicyService<CustomCorsPolicyService>();
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
// Add this before any other middleware that might write cookies
app.UseCookiePolicy();
app.UseIdentityServer();
app.UseRouting();
app.UseCors();
app.UseMvcWithDefaultRoute();
// This will write cookies, so make sure it's after the cookie policy
app.UseAuthentication();
}
In My Controller
[ApiController]
public sealed class EmbeddedLogController : ControllerBase
{
[HttpPost]
[Route("/embedded/log/")]
[EnableCors()]
public ActionResult Log(ParametersLog parameters)
{
....
}
}
Without CustomClientStore I could call services.AddCors(setup => setup.AddDefaultPolicy... to accept CORS
But now I need to use builder.AddClientStore<CustomClientStore>(); because of CustomProfileService.
How can I fix that ?
Thanks
this GitHub issue might give you some clues.
That says:
Solved When using Endpoint Routing CORS and IdentityServer4, the call
to UseCors() must be after UseRouting() but BEFORE UseIdentityServer()
and UseAuthorization(). Otherwise it will appear to work but
Pre-Flight checks will fail

Disable ApiVersioning for OData controllers

is there any way to disable ApiVersioning only for OData controllers?
I have an application in which there are REST controllers and OData controllers. The problem occurs when I add AddApiVersioning. REST Controllers work as they should. OData controllers returns HTTP ERROR 404.
If I remove AddApiVersioning then OData controllers work properly.
The application is running on ASP.NET Core 3.1
public void ConfigureServices(IServiceCollection serviceCollection)
{
...
serviceCollection.AddOData();
serviceCollection.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
});
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
...
app.UseEndpoints(endpoints =>
{
...
endpoints.EnableDependencyInjection();
endpoints.MapODataRoute("odata", "/odata", ODataConfiguration.GetEdmModel());
...
});
...
}
Thank you for answer.

CORS Error: No 'Access-Control-Allow-Origin' header is present on the requested resource

I am using .Net Core 3. I have programmed an API being called by a SPA hosted in a .Net Core Web Project.
For one POST action in the API, I get a CORS error in Chrome as well as Firefox while for another POST action in the same controller of the API, everything works fine.
The error that I get is
Access to fetch at 'https://subdomain1.domain1.com:50003/api/v1/projects/project' from origin
'https://subdomain2.domain2.com:50002' has been blocked by CORS policy:
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.
In the API,
In the startup class, I have following
readonly string MyAllowSpecificOrigins = "AllowOrigin";
public void ConfigureServices(IServiceCollection services)
{
CorsPolicyBuilder builder = new CorsPolicyBuilder();
CorsPolicy policy = builder.WithOrigins("https://subdomain2.domain2.com:50002")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.Build();
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins, policy);
});
services.AddControllers();
services
.AddAuthentication("Bearer")
.AddJwtBearer(jwtOptions => {
jwtOptions.Authority = "https://subdomain.domain.com:50001";
jwtOptions.Audience = "portal-api";
jwtOptions.RequireHttpsMetadata = false;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".hrc"] = "application/octet-stream";
provider.Mappings[".obj"] = "application/octet-stream";
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers().RequireCors(MyAllowSpecificOrigins);
});
app.UseMvc();
}
In the API controller, I have a POST action for which I don't get any CORS error
[HttpPost]
[Route("[action]")]
[ActionName("thumbnail")]
public async Task<IActionResult> thumbnail([FromBody]dataDTO model)
{
.
.
.
}
In the same API, I have another POST action, for which the browser gives the above mentioned CORS error
[HttpPost]
[Route("project")]
[ActionName("project")]
public async Task<IActionResult> projectAdd([FromBody]projectDTO project)
{
.
.
.
}
I have already tried moving the app.UseCors(MyAllowSpecificOrigins); to the top of configure function in startup.cs. It did not help.
I have also tried moving the app.UseCors(MyAllowSpecificOrigins); statement and changing its order in configure with no difference.
In firefox, I have also verified that there is a Origin header in the request to the action for which we are getting CORS error.

Redirect to HTTPS in Blazor

I have a blazor app.
I hosted it on server and have access with https.
But when i do redirect (in one controller), happens exception.
Startap.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCompression();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseMvc(routes =>
{
routes.MapRoute(name: "default", template: "{controller}/{action}/{id?}");
});
app.Map("/schedule", subdirApp =>
{
subdirApp.UseBlazor<Client.Startup>();
});
}
And method in controller
[HttpGet]
[Route("***")]
public IActionResult Return()
{
FileStream fs = new FileStream(_filePath, FileMode.Open);
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
List<ScheduleEntity> _list = (List<ScheduleEntity>)formatter.Deserialize(fs);
foreach (var x in _list)
Schedules.Add(x);
fs.Close();
return Redirect("~//schedule");
}
Exception
Please, help me
These API responses can be a bit misleading. Without seeing the rest of your code around the configuration of endpoints, I suspect this might be a CORS issue with the API.
Try adding the following code to the public void Configure(IApplicationBuilder app, IHostingEnvironment env) method in your API's Startup.cs class:
app.UseCors(opts => opts
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
The fetch response may be due to the request preflight being rejected.
Having said that, the first exception message is saying you're trying to load insecure content, so I'd also check your Blazor front-end app's configuration to see what the API client is requesting and ensure the API endpoint certificate is valid?