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

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.

Related

CORS issue with PUT request from reactjs to asp.netCore api

I am working on a Reactjs app with Asp.netCore API with Sql database
deployed to IIS server.
All the operation is working except PUT operation on the task
it break with CORS error and the request is not reaching the backend, I tested it locally and it's working fine. Tested using Postman and it's working too even the deployed version is working with postman. I can't figure out what's the issue or from where I should start debugging.
startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy(name: CorsPolicy, builder =>
{
builder.WithOrigins(FrontEnd_URL).SetIsOriginAllowed((host) =>
true).AllowAnyHeader().AllowAnyMethod().AllowCredentials();
}));
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseCors(CorsPolicy);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapHub<TrelloHub>("/trello");
});
}
TaskController
[Route("/api/tasks")]
[ApiController]
public class TasksController : Controller
{
private readonly IMapper _mapper;
private readonly ITaskService _taskService;
public TasksController(ITaskService taskService , IMapper mapper)
{
_mapper = mapper;
_taskService = taskService;
}
[HttpPut("{id:int}", Name = "UpdateTask")]
public async Task<String> UpadateTask([FromBody]TaskDto taskdto, int id)
{
var taskModel = _mapper.Map<Task>(taskdto);
return await _taskService.UpadateTask(id , taskModel);
}
}
first check IIS server logs. it can help you a lot, also look at the request headers of the reactjs client origin: header exactly and add it to the allowed origins

My razor pages are not working all of the generate the same error : Localhost page cant be found

This is my startup.cs file
Does anyone know whats going wrong This is my index.cshtml
Alright so my code will be below its very basic startup.cs file and a index.cshtml file with some basic code just for testing
public class Startup
{
// 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.AddRazorPages();
}
// 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();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}}
#page
#DateTime.Now
Try to create a new project and check whether you have the same problem.
And did you apply something to your service side? You can share it.
Or you can try these code first:
ConfigureServices:
services.AddMvc(options =>
{
options.EnableEndpointRouting = false;
});
Configure:
app.UseMvcWithDefaultRoute();

Asp.net Web API .NET Core 3.1 and Azure AD - system.unauthorizedaccessexception: neither scope or roles claim was found in the bearer token

I am trying to secure my Web Api with Azure AD. This application will be accessed by a console app, and the token will be generated from a client id / secret. I followed the quickstart from https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-v2-aspnet-core-web-api .
After obtaining a client token and sending through the bearer auth header, I am getting an error
System.UnauthorizedAccessException: IDW10201: Neither scope or roles claim was found in the bearer token.
I'm obtaining an access token with this code:
public static async Task<string> GetAccessToken(string aadInstance, string aadTenant, string aadClientId, string aadClientSecret, string apiResourceId)
{
string authority = aadInstance.TrimEnd('/') + "/" + aadTenant;
var app = ConfidentialClientApplicationBuilder.Create(apiResourceId)
.WithClientId(aadClientId)
.WithClientSecret(aadClientSecret)
.WithAuthority(authority)
.Build();
var tokenrequest = app.AcquireTokenForClient(new string[] { "api://resourceid/.default" });
var tokenresult = await tokenrequest.ExecuteAsync();
return tokenresult.AccessToken;
}
My startup code in the web api looks like this:
public void ConfigureServices(IServiceCollection services)
{
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration);
later in the startup...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseOpenApi();
app.UseSwaggerUi3();
}
It turns out that the setup in Azure AD was missing a role that needed to be added to the manifest as well as the permissions to the api of the client application, as per step 8 in https://dotnetplaybook.com/secure-a-net-core-api-using-bearer-authentication/
Unfortunately the MS documentation doesn't put this part in the quick start.

Asp.net core 2.0 mvc application get client ip address with load balancer option

I am unable to get client IP address using .net core 2.0 application.
I used the below code in startup.cs file.
I used the below code in homecontriller.cs file.
I am getting remoteIpAddress is 1.0.0.0 in local. when I deployed in the server I got server IP address but I want to display the client IP address.
can you please help with this. thanks.
services.Configure<ForwardedHeadersOptions> (options => {
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor> ();
services.AddHttpContextAccessor();
services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor> ();
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
app.UseForwardedHeaders(new ForwardedHeadersOptions {
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
}
public IActionResult Index() {
string remoteIpAddress = HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
if (Request.Headers.ContainsKey("X-Forwarded-For")) {
remoteIpAddress = Request.Headers["X-Forwarded-For"];
}
ViewBag.ip1 = remoteIpAddress.ToString();
return View();
}
In project.json add a dependency to:
"Microsoft.AspNetCore.HttpOverrides": "1.0.0"
In Startup.cs, in the Configure() method add:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto
});
and in controller
using Microsoft.AspNetCore.HttpOverrides;
then by this way you can get the IP address
Request.HttpContext.Connection.RemoteIpAddress

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?