Following the answer on this question, I have added authorization on everything by default, using the following code:
public void ConfigureServices(IServiceCollection aServices)
{
aServices.AddMvc(options =>
{
var lBuilder = new AuthorizationPolicyBuilder().RequireAuthenticatedUser();
var lFilter = new AuthorizeFilter(lBuilder.Build());
options.Filters.Add(lFilter);
});
aServices.AddMvc();
}
public void Configure(IApplicationBuilder aApp, IHostingEnvironment aEnv, ILoggerFactory aLoggerFactory)
{
aApp.UseCookieAuthentication(options =>
{
options.AuthenticationScheme = "Cookies";
options.AutomaticAuthentication = true;
});
}
However when someone tries to access something unauthorized, it returns a (what seems a default) redirect URL (http://foo.bar/Account/Login?ReturnUrl=%2Fapi%2Ffoobar%2F).
I want it to return a HTTP 401 only, instead of a redirect.
How can I do this in ASP.NET 5 for a WebAPI?
I had with this problem in an Angular2 + ASP.NET Core application. I managed to fix it in the following way:
services.AddIdentity<ApplicationUser, IdentityRole>(config => {
// ...
config.Cookies.ApplicationCookie.AutomaticChallenge = false;
// ...
});
If this is not working for you, you can try with the following method instead:
services.AddIdentity<ApplicationUser, IdentityRole>(config => {
// ...
config.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = ctx =>
{
if (ctx.Request.Path.StartsWithSegments("/api"))
{
ctx.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
// added for .NET Core 1.0.1 and above (thanks to @Sean for the update)
ctx.Response.WriteAsync("{\"error\": " + ctx.Response.StatusCode + "}");
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.FromResult(0);
}
};
// ...
}
Update for Asp.Net Core 2.0
Cookie options are now configured in the following way:
services.ConfigureApplicationCookie(config =>
{
config.Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = ctx => {
if (ctx.Request.Path.StartsWithSegments("/api"))
{
ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
}
else {
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.FromResult(0);
}
};
});
Question/clarification -- Why should we check for HTTP 200 before changing it? If the redirect is happening, shouldn't we just act regardless? Thanks in advance.
Updated answer accordingly.
Nice answer, pointed me in the right direction. You might also want to use OnRedirectToAccessDenied for authenticated (logged in) but not authorized users with HttpStatusCode.Forbidden for the api case and a redirect without the ReturnString for View users.
This is the correct answer for ASP.NET MVC Core, and with Angular 2 apps. Thank you!!!! Drove me bunkers. Note: this is required when using JWT token auth via cookies - especially when switching from JWT bearer auth.
Doesn't seem to work for .NET core 3.0 (preview) :/