gettting 401 on Hangfire with LocalRequestsOnlyAuthorizationFilter - hangfire

We are trying to use hangfire with LocalRequestsOnlyAuthorizationFilter. We have deployed the application to IIS. When trying to access the hangfire dashboard from same machine where IIS is deployed, we are getting 401 on hangfire dashboard URL "/jobs". All we are trying to do here is allow to view the dashboard as long as request is coming from same machine where hangfire is deployed. Below is our config on startup.cs file
public void Configure(IApplicationBuilder app, IBackgroundJobClient backgroundJobs, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseHangfireDashboard("/jobs", new DashboardOptions()
{
Authorization = new[] { new LocalRequestsOnlyAuthorizationFilter() }
});
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapHangfireDashboard();
});
backgroundJobs.Enqueue(() => Console.WriteLine("Hello world from Hangfire!"));
}
We checked both remote and local ip and both are same. Is there anything else we are missing here? Just to make sure application is running or not on IIS, we are added the another page and that page is working fine.

Change your Authorization to AuthorizationFilters,
app.UseHangfireDashboard("/jobs", new DashboardOptions()
{
AuthorizationFilters = new[] { new LocalRequestsOnlyAuthorizationFilter() }
});
Also, from this post check to make sure ASP.net is correctly installed and integrated pipeline is used for your application pool
This is also another good resource to go through in validating your IIS configuration

Related

How to set the redirect URI when using Microsoft sign-in in a .NET 5 application?

I have created a .NET 5 application with Microsoft sign-in based on this explanation.
It is working fine when running locally. However, something is going wrong when running the application in Amazon EKS. This became clear to me after reading error message I saw in the browser and after reading the network traffic.
This is how this looks like.
What becomes clear is that there is something wrong with "redirect_uri" (containing http instead of https). This is really frustrating as my application is using https. I use https when opening the application in my browser. It is important to mention that this does not occur when running the application locally on my laptop. What I hope for is that there is a simple way to set the "redirect_uri" property that is used in my code. In this way, I can guarantee that the right redirect uri is used.
Here is the source code I would like to change:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var configSettings = new ConfigSettings();
Configuration.Bind("ConfigSettings", configSettings);
services.AddSingleton(configSettings);
services.AddSingleton<IAuthResponseFactory, AuthResponseFactory>();
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddRazorPages()
.AddMicrosoftIdentityUI();
services.AddHealthChecks();
services.Configure<HealthCheckPublisherOptions>(options =>
{
options.Delay = TimeSpan.FromSeconds(2);
options.Predicate = (check) => check.Tags.Contains("ready");
});
}
// 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("/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.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.UseEndpoints(endpoints =>
{
endpoints.MapHealthChecks("/health/ready", new HealthCheckOptions()
{
Predicate = (check) => check.Tags.Contains("ready")
});
endpoints.MapHealthChecks("/health/live", new HealthCheckOptions());
});
}
So how do I change my source in a way that I can set the redirect uri correctly?
Looks like you need to enable header forwarding.
Step 1: configure the ForwardedHeadersOptions
services.Configure<ForwardedHeadersOptions>(options =>
{
options.RequireHeaderSymmetry = false;
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
// TODO : it's a bit unsafe to allow all Networks and Proxies...
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
Step 2: UseForwardedHeaders in the public void Configure(IApplicationBuilder app, IHostingEnvironment env) method
app.UseForwardedHeaders();
Step 3: Only use UseHttpsRedirection for production
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// Forward http to https (only needed for local development because the Azure Linux App Service already enforces https)
app.UseHttpsRedirection();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
See How to set redirect_uri protocol to HTTPS in Azure Web Apps and .net Core X Forwarded Proto not working

Microsoft.Web.Identity nuget >=1.9.2 breaks AppService/Azure AD login with 401 response

Testing with a plain vanilla (out of the box sample asp.net 5 MVC web app from VS2019), hosted on an Azure app service (backed with a linux app service plan). Nothing changed or added, except adding an [Authorize] tag to test against a single view from the default controller.
Default App Service in Azure, with a default app registration in Azure AD.
I've noticed every version of Microsoft.Web.Identity >=1.9.2 will break when running in the app service (but works fine locally). When attempting to reach the protected view, it will return a 401. Downgrading to 1.9.1 will redirect me to a login page. Is there some additional configuration that I am missing?
my appsettings configuration
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "mydomain.org",
"TenantId": "XXX",
"ClientId": "XXX",
"CallbackPath": "/signin-oidc",
"SignedOutCallbackPath": "/signout-oidc"
},
my startup.cs
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.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddRazorPages()
.AddMicrosoftIdentityUI();
}
// 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("/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.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}

Handling Server side routing errors with built in client side routing .NET 5

I have a question regarding the cleanest/easiest way to fix a routing issue. To start off, I'm using the .NET 5 framework, and have the following setup in my Startup.cs:
public void ConfigureServices(IServiceCollection services) {
...
services.AddSpaStaticFiles(configuration => { configuration.RootPath = "UI"; });
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
...
app.UseRouting();
app.UseSpaStaticFiles();
app.UseAuthorization();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
app.UseSpa(spa =>
{
if (!env.IsDevelopment()) return;
spa.Options.SourcePath = "UI/";
spa.UseVueCli();
});
...
}
Now, my problem seems to be an issue with the server side routing behavior, however I will let you diagnose. Basically, I am returning a Redirect method that redirects to a CLIENT SIDE route, (the route does NOT exist on the server side), and so when my client receives the response, it always receives the response as a 404 error message. However, if I click the request in the network tab in my browser debugger, it ends up redirecting to the client endpoint properly. I was wondering how I could resolve this 404 error and smoothly redirect to that client endpoint.
Thanks

User.Identity with empty properties when running app on Kestrel

I have two situations during windows authentication using Active Directory domain identities:
When I running my app with IIS I'm getting object WindowsPrincipal filled with information
When I running my app with Kestrel I'm getting object ClaimsPrincipal without any informatiion about the user information
What could be the problem?
My ConfigureService:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<IdentityUser, IdentityRole>().AddRoleManager<RoleManager<IdentityRole>>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationContext>();
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate();
services.AddAuthorization();
services.AddScoped<IUserManagementManager, UserManagementManager>();
services.AddScoped<IRolesManagementManager, RolesManagementManager>();
}
Configure:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger<Startup> logger)
{
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.UseResponseCaching();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Authentication}/{action=Index}");
});
}
How did you configure Windows Authentication in the Kestrel? I found that the attribute of IsAuthenticated in your image is false. This may cause you can not get any information about the ClaimsPrincipal.
You can use invoke AddAuthentication and AddNegotiate in Startup.ConfigureServices to add authentication services in Kestrel.
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
.AddNegotiate();
More information about how to config windows Authentication in the Kestrel you can refer to this link: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-5.0&tabs=visual-studio

.MapWhen executing for all calls

I have a large already running application built on .net core 1.0.4. I have a need to add a micro api to this application, and am attempting to integrate a fairly simple http basic auth middleware into the pipeline only for calls to the api controller.
In my startup.csconfigure method, I have the following.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//run basic auth only on API calls
app.MapWhen(context => context.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase), appBuilder =>
{
app.UseMiddleware<BasicAuthenticationMiddleware>();
app.UseMvc();
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/site/error");
}
app.UseStaticFiles();
app.UseIdentity();
app.UseDefaultFiles();
app.UseStatusCodePages();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Site}/{action=Login}/{id?}");
});
}
It's my understanding that the pipeline would branch for all calls that start with /api into the Basic middle ware. My issue is that with this code, ALL calls regardless of the path are hitting the .MapWhen path, and essentially breaking the entire site.