API access unauthorized unless AuthenticationScheme is specified - asp.net-core

I'm in the process of learning Asp.Net Core Identity along with Identity Server 4. So far I have got my User authenticated against IdS4, then I can get a token to use access my API, this all works as expected, however I always need to create my Authorization Attributes on my API controller with a specified AuthenticationScheme parameter, even though I specify it my API's Config.cs (according to several sources/guides I have read).
This is my API's Config.cs, I have left the different attempts commented out. Each version hasn't has any effect, occasionally a 500 error instead of a 401, but that will be down to me doing something very wrong!
Config.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationCoreDbContext>(opt => opt.UseInMemoryDatabase("TestItem"));
services
.AddMvc();
services
//.AddAuthentication(cfg =>
//{
// cfg.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
// cfg.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
//})
.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
//.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
options.Authority = "https://localhost:5001";
options.RequireHttpsMetadata = false;
options.ApiName = "web_api";
options.EnableCaching = true;
options.CacheDuration = TimeSpan.FromMinutes(10);
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Here is a sample endpoint from my API Controller. In it's current state it works fine, however I believe I shouldn't need to specify the AuthenticationSchemes, but if I remove it, I always get a 401 error. Does anyone have any suggestions on what I'm missing?
API Controller
// GET: api/TestItems
[HttpGet]
//[Authorize]
[Authorize(AuthenticationSchemes = "Bearer")]
public async Task<ActionResult<IEnumerable<TestItemDto>>> GetTestItems()
{
//SNIP
}

Issue is because of order of middleware added in the Startup.Configure method. Proper order is critical for security. Read more here.
In this case you move app.UseAuthorization() to be after app.UseAuthentication(). The code would be like:
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();
});
}

Related

Is this usage of CORS correct?

While in VS2019 Debugging (IIS Express) an API service and web application using the service I receive "Access to XMLHttpRequest at 'theservice' from origin 'apporigin' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource".
Startup Methods
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddCors();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseCors(options => {
options.AllowAnyOrigin();
});
}
Controller Class and Get Method both have the [EnableCors()] attribute.
To me, this seems correct however I continue to receive the missing origin header message. Am I implementing CORS correctly in this case?
UseCors must be called in proper order. It must be placed after UseRouting, but before UseAuthorization. You can refer this document.
Not every middleware needs to go in this exact order, but many do. For example:
UseCors, UseAuthentication, and UseAuthorization must go in the order shown.
UseCors currently must go before UseResponseCaching due to this bug.
https://stackoverflow.com/users/6527049/vivek-nuna has the answer in Comments.
move app.UseCors(options => {options.AllowAnyOrigin();}); to after app.UseRouting() and before app.UseAuthorization()
The correct Configure Method looks like this:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(options => {
options.AllowAnyOrigin();
});
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}

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();

.NET Core compression does not work in my controller

I just created a new .NET Core 3.1 Web API project based by the template in VS 2019, and I added code following the official example in startup.cs like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCompression();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
but the compression middleware does not work
webapi response in browser
.Net Core Response Compression is disabled by default for HTTPS traffic, which it appears you are using. Try changing your call to AddResponseCompression() to turn it on for https.
services.AddResponseCompression(options =>
{
options.EnableForHttps = true;
});
You can see the MS docs for use of response compression with https, as there are security implications noted in the article. https://learn.microsoft.com/en-us/aspnet/core/performance/response-compression?view=aspnetcore-3.1#compression-with-secure-protocol

How does Authentication works in asp.net core3.0?

I have the following code in Startup.cs file
public void ConfigureServices(IServiceCollection services)
{
services.
AddAuthentication("CookieAuth").
AddCookie("CookieAuth", config =>
{
config.Cookie.Name = "user.cookie";
config.LoginPath = "/Home/Login";
});
services.AddControllersWithViews();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();//determining a user's identity
app.UseAuthorization();//determines what a user is able to do
app.UseEndpoints(opt => {
opt.MapDefaultControllerRoute();
});
}
The above configuration works fine, it doesn't have any exception. But I can't figure out how the Authentication works. I have known the following concepts:
Authentication determines the user's identity.
Authorization determines what a user is able to do.
I didn't know the execution sequential. I mean:
does the Authentication always check the user's identity per request? Even though these requests are in the same session?
What's will happen if a request doesn't have a valid user's identity(e.g: on the first request)? is it going to continue executing the Authorization?

How to set default razor page route with asp.net 3.0 middleware

So to setup endpoint routing in asp.net core 3.x, we do something like this
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//...
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
}
How/where can we define a "default" page route other than index?
The easiest solution would be to manually add route to the custom page in ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(o => o.Conventions.AddPageRoute("/CustomPage", ""));
}
With this solution you need to rename or remove Index page to avoid AmbiguousMatchException
This is an example of a default route.
app.UseEndpoints(endpoint =>
{
endpoint.MapDefaultControllerRoute();
});