Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asp.net core authorization redirect to specified path on failure

In "old" ASP.NET I could build a custom authorize attribute and override HandleUnauthorizedRequest. I cannot seem to do this with ASP.NET Core using a custom authorization handler. The latter either "succeed" or "fails" and I would like to redirect to alternative controller actions based on the nature of the failure.

Here's the scenario. Users of my web app have a claim which indicates that they are "active" users, i.e. they have fully registered and we have validated their details etc. New users have been authenticated using the OpenIdConnect middleware but, until we have fully validated and set up their account, do not have the "active" user claim. Thus, both new users and active users have been authenticated. I want to prevent new users accessing most of the application. Every time they try to get to https://app.example.com/dashboard I want to redirect them to a https://app.example.com/newuser page, from which they can go through the set up process.

I can use an authorization policy on my controllers to check for the presence of the "active" user claim and allow access. When a new user doesn't have this claim, and fails the authorization, I want the authorization handler to have some logic which then redirects them to an area of the app which they do have access to. But I cannot see how to do this using the authorization framework in ASPNET core.

There is a somewhat clunky solution which uses the CookieMiddleware and implements a handler for the OnRedirectToAccessDenied event - see https://github.com/aspnet/Mvc/issues/4890. I also thought about implementing an action filter which runs on every request.

Am I just being stupid here? Surely, it makes sense to want to carry out some action on authorization failures which doesn't just send the user off to re-authenticate.

like image 886
jcaddy Avatar asked Aug 04 '17 14:08

jcaddy


1 Answers

After some digging about and referring to the wonderful book, Pro ASP.NET Core MVC (6th Edition, Adam Freeman), the simple answer to my question is to create an Authorization Filter. This implements IAuthorizationFilter with a single method OnAuthorization(AuthorizationFilterContext context). In this method do whatever you need to do to check the request. If it fails authorization simply set the context.Result property to some IActionResult, in my case RedirectToActionResult. If the request passes authorization do nothing.

You can also use dependency injection in the filter - fantastic.

There is no mention on how to implement or code samples for IAuthorizationFilter on the Microsoft ASP.NET docs site. Thanks are to Adam Freeman.

like image 121
jcaddy Avatar answered Oct 16 '22 12:10

jcaddy