I\'m trying to get ASP.NET Core Identity to return 401 when a user isn\'t logged in. I\'ve added an [Authorize]
attribute to my method and instead of returning
Okay after digging around in the asp.net core unit tests I finally found a working solution. You have to add the following to your call to services.AddIdentity
services.AddIdentity<ApplicationUser, IdentityRole>(o => {
o.Cookies.ApplicationCookie.AutomaticChallenge = false;
});
For ASP.NET Core 3.x (preview) using Identity with Cookie authentication this is what did the trick:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<IdentityContext>()
.AddDefaultTokenProviders()
.AddRoles<IdentityRole>();
services.ConfigureApplicationCookie(options =>
{
options.Events.OnRedirectToLogin = context =>
{
context.Response.Headers["Location"] = context.RedirectUri;
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
});
This is what we see around everywhere in different variations. BUT, the essential point here is that ConfigureApplicationCookie
must be specified AFTER AddIdentity
. It's "sad" but true. This SO answer finally brought light in the darkness.
I have been scratching my head for over a day and tried many different variations:
ApplicationCookie
(but before the call to AddIdentity
which doesn't work.That all didn't work. But with the answer above I finally got the 401 Unauthorized returned (which should be Unauthenticated by the way)
For me on ASP.NET Core 2.2.0 only this worked:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(
options =>
{
options.LoginPath = new PathString("/Account/Login");
options.LogoutPath = new PathString("/Account/Logout");
options.Events.OnRedirectToLogin = context =>
{
if (context.Request.Path.StartsWithSegments("/api")
&& context.Response.StatusCode == StatusCodes.Status200OK)
{
context.Response.Clear();
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
}
context.Response.Redirect(context.RedirectUri);
return Task.CompletedTask;
};
}
);
services.Configure<IdentityOptions>(options =>
{
options.Cookies.ApplicationCookie.LoginPath = new PathString("/");
options.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents()
{
OnRedirectToLogin = context =>
{
if (context.Request.Path.Value.StartsWith("/api"))
{
context.Response.Clear();
context.Response.StatusCode = 401;
return Task.FromResult(0);
}
context.Response.Redirect(context.RedirectUri);
return Task.FromResult(0);
}
};
});
Source:
https://www.illucit.com/blog/2016/04/asp-net-5-identity-302-redirect-vs-401-unauthorized-for-api-ajax-requests/
As of ASP.NET Core 2.x:
services.ConfigureApplicationCookie(options =>
{
options.Events.OnRedirectToLogin = context =>
{
context.Response.StatusCode = 401;
return Task.CompletedTask;
};
});
For asp.net mvc core USE THIS INSTEAD
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
options.LogoutPath = new PathString("/Account/Logout");
options.Events.OnRedirectToLogin = context =>
{
if (context.Request.Path.StartsWithSegments("/api")
&& context.Response.StatusCode == StatusCodes.Status200OK)
{
context.Response.Clear();
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
}
context.Response.Redirect(context.RedirectUri);
return Task.CompletedTask;
};
});