What is the default behavior of violating the Authorize
attribute in ASP.NET Core?
[Authorize(Roles = "Administrator")]
public ActionResult ShutDown()
{
}
It seems that it redirects to the /Account/AccessDenied
if the user doesn't have enough rights and /Account/Login
if the user didn't login yet.
Am I right?
I don't see anything about it in the docs.
It depends on which authentication middleware you're using.
The cookie based authentication middleware will, by default, redirect an unauthenticated user to /Account/Login, and an already authenticated user to /Account/AccessDenied. This behaviour can be turned off by setting the AutomaticChallenge flag in the middleware options, as which point it will just return an HTTP 401 response when the user is not logged in, or 403 when the user is logged in, but doesn't fulfill the authorization requirements.
JWT bearer middleware will only return 401 or 403 status codes.
Other middlewares may behave differently, depending on what standard they are trying to implement.
I thought it might be useful to follow the code and understand what is going on. The default AuthenticationHandler
will just return 401(Unauthenticated) or 403(Forbidden). After that, depending on your project configuration different authentication handlers will be added to the pipeline.
AddIdentity
and UseIdentity
, you also call UseCookieAuthentication
behind the scenes, which in turn adds the CookieAuthenticationMiddleware
. CookieAuthenticationMiddleware
will replace the default handler with the CookieAuthenticationHandler
, although by default the previous handler will be kept as the prior handler. That way handlers might decide not to participate and let the previous handler handle the result. (This is important to understand how the AutomaticChallenge
flag works)CookieAuthenticationHandler
will redirect to the AccessDeniedPath
or the LoginPath
which are taken from the options. By default these paths are /Account/Login
and /Account/AccessDenied
but they can be overriden by Identity when it calls UseCookieAuthentication. (Only LoginPath is overriden but the same value is used).You could manually update those paths as well, for example:
services.AddIdentity<ApplicationUser, IdentityRole>(opts =>
opts.Cookies.ApplicationCookie.LoginPath = new PathString("/Account/my-login"));
The AutomaticChallenge
flag mentioned by @blowdart is set as true by default when Identity adds the cookie authorization middleware. When you set that as false, the cookie handler will not participate and the prior handler will be executed, returning 401 or 403. (As the prior handler will be defaul the default one)
services.AddIdentity<ApplicationUser, IdentityRole>(opts =>
opts.Cookies.ApplicationCookie.AutomaticChallenge = false);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With