ASP.NET MVC redirect to an access denied page using a custom role provider

前提是你 提交于 2019-12-29 10:06:35

问题


I'm creating a custom role provider and I set a Authorize attribute specifying a role in my controller and it's working just fine, like this:

[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...

But when an user doens't have access to this controller, he's redirected to login page. How can I redirect him to a "AcessDenied.aspx" page?


回答1:


[AccessDeniedAuthorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller

AccessDeniedAuthorizeAttribute.cs:

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if(filterContext.Result is HttpUnauthorizedResult)
        {
            filterContext.Result = new RedirectResult("~/AcessDenied.aspx");
        }
    }
}



回答2:


Here's my solution, based on eu-ge-ne's answer. Mine correctly redirects the user to the Login page if they are not logged in, but to an Access Denied page if they are logged in but are unauthorized to view that page.

[AccessDeniedAuthorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller

AccessDeniedAuthorizeAttribute.cs:

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectResult("~/Account/Logon");
            return;
        }

        if (filterContext.Result is HttpUnauthorizedResult)
        {
            filterContext.Result = new RedirectResult("~/Account/Denied");
        }
    }
}

AccountController.cs:

public ActionResult Denied()
{
    return View();
}

Views/Account/Denied.cshtml: (Razor syntax)

@{
    ViewBag.Title = "Access Denied";
}

<h2>@ViewBag.Title</h2>

Sorry, but you don't have access to that page.



回答3:


Take a look at tvanfosson's Answer from this very similar question, This is what I am doing(Thanks to tvanfosson), so now I just have to say:

[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")]
public class SuperAdminController : Controller
...

If the user is not in the role, they will get thew view specified by ViewName.




回答4:


A slight improvement to Matt's answer by avoiding the need to hard-code the Logon page and optionally setting the access denied view within the attribute:

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public string AccessDeniedViewName { get; set; }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
            filterContext.Result is HttpUnauthorizedResult)
        {
            if (string.IsNullOrWhiteSpace(AccessDeniedViewName))
                AccessDeniedViewName = "~/Account/AccessDenied";

            filterContext.Result = new RedirectResult(AccessDeniedViewName);
        }
    }
}



回答5:


Redirect is not always the best solution

Use standard http code 403:

return new HttpStatusCodeResult(HttpStatusCode.Forbidden);



回答6:


public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            if (filterContext.Result is HttpUnauthorizedResult && WebSecurity.IsAuthenticated)
            {
                filterContext.Result = new RedirectResult("~/Account/AccessDenied");
            }
        }
    }



回答7:


I've built on Vic's answer to allow me to have a different Access Denied page for each of the application's areas. Did it by returning a RedirectToRouteResult instead, which instead of redirecting to a URL relative to the root of the application it redirects to the current area's controller and action:

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public string AccessDeniedController { get; set; }
    public string AccessDeniedAction { get; set; }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
            filterContext.Result is HttpUnauthorizedResult)
        {
            if (String.IsNullOrWhiteSpace(AccessDeniedController) || String.IsNullOrWhiteSpace(AccessDeniedAction))
            {
                AccessDeniedController = "Home";
                AccessDeniedAction = "AccessDenied";
            }

            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Controller = AccessDeniedController, Action = AccessDeniedAction }));
        }
    }
}



回答8:


Just a small update to Vic Alcazar, Added details of the request url in redirect So that can log the details of the access denied and by who if want

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public string AccessDeniedViewName { get; set; }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
            filterContext.Result is HttpUnauthorizedResult)
        {
            if (string.IsNullOrWhiteSpace(AccessDeniedViewName))
                AccessDeniedViewName = "~/Account/AccessDenied";

            var requestUrl = filterContext.HttpContext.Request.Url;

            filterContext.Result = new RedirectResult(String.Format("{0}?RequestUrl={1}", AccessDeniedViewName, requestUrl));
        }
    }
}


来源:https://stackoverflow.com/questions/1279643/asp-net-mvc-redirect-to-an-access-denied-page-using-a-custom-role-provider

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!