Redirecting unauthorized access to a page in MVC for user view

I have an MVC website in which access is based on different roles. As soon as the user logs in, they can see the navigation to the pages for which they are authorized. However, some users may still try to access the pages using the direct URL. If so, the system automatically redirects them to the login page. Instead of the login page, I want to redirect them to another view (unauthorized).

Web.Config has the following entry:

<customErrors mode="On"> <error statusCode="401" redirect="~/Home/Unauthorized" /> <error statusCode="404" redirect="~/Home/PageNotFound" /> </customErrors> <authentication mode="Forms"> <forms name="Development" loginUrl="~/Account/Login" cookieless="UseCookies" timeout="120"></forms> </authentication> 

I also registered these routes at Global.asax.cs.

 routes.MapRoute( name: "Unauthorized", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Unauthorized", id = UrlParameter.Optional } ); routes.MapRoute( name: "PageNotFound", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "PageNotFound", id = UrlParameter.Optional } ); 

Would that be enough?

+7
authorization asp.net-mvc unauthorized
source share
4 answers

Next time it works

 public class CustomAuthorize : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { //filterContext.Result = new HttpUnauthorizedResult(); // Try this but i'm not sure filterContext.Result = new RedirectResult("~/Home/Unauthorized"); } public override void OnAuthorization(AuthorizationContext filterContext) { if (this.AuthorizeCore(filterContext.HttpContext)) { base.OnAuthorization(filterContext); } else { this.HandleUnauthorizedRequest(filterContext); } } } 

And then apply to Controller or Action, as shown below:

 [CustomAuthorize(Roles = "Admin")] 

With the above approach, I need to review all the controller / actions and change the Authorized attribute! Some testing will also be required.

I'm still not sure why Web.Config traffic does not work as described in the MVC documentation. Maybe something has changed in MVC 4!

+12
source share

After some research, I believe that the simplest answer to this problem is simply to create a custom authorization very similar to jbbi (but this did not work, since "new HttpUnauthorizedResult ()" is internally automatically redirected to the input - at least in mvc 5 with identity)

 public class CustomAuthorize : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { //if not logged, it will work as normal Authorize and redirect to the Login base.HandleUnauthorizedRequest(filterContext); } else { //logged and wihout the role to access it - redirect to the custom controller action filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Error", action = "AccessDenied" })); } } } 

and use will be the same as default authorization:

 [CustomAuthorize(Roles = "Administrator")] 

Then, to do everything right, remember to send the http code of the error page. FE like this in the controller.

 public ActionResult AccessDenied() { Response.StatusCode = 403; return View(); } 

It's easy, it works, and even I (.net mvc rookie) understand that.

Note. . This does not work with 401 code - it will always use 401 and internally redirect it to login. But in my case, by definition, 403 is also suitable.

+14
source share

Probably the best way to handle this is to create an additional action filter that redirects the user to the specified error page if he does not belong to the specified role. Thus, both filters will be used in these methods: [Authorize] (without roles) to protect against unauthorized users and redirect them to the login page. And your custom attribute with roles. Code MEETS THIS (not verified):

 public class RoleFilterAttribute : ActionFilterAttribute { public string Role { get; set; } public override void OnActionExecuting(ActionExecutingContext ctx) { // Assume that we have user identity because Authorize is also // applied var user = ctx.HttpContext.User; if (!user.IsInRole(Role)) { ctx.Result = new RedirectResult("url_needed_here"); } } } 

Apply both the [Authorize] and [RoleFilter] actions to the actions ...

Hope this helps!

+2
source share

I think you should create your own authorization filter attribute, which inherits the default authorization filter

 public class CustomAuthorize: AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { filterContext.Result = new HttpUnauthorizedResult(); // Try this but i'm not sure } } 
0
source share

All Articles