ASP.NET MVC使用自定义角色提供程序重定向到访问被拒绝页面

时间:2009-08-14 19:10:08

标签: asp.net-mvc asp.net-membership roleprovider

我正在创建一个自定义角色提供程序,并设置了一个Authorize属性,在我的控制器中指定了一个角色,它的工作正常,如下所示:

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

但是当用户无法访问此控制器时,他会被重定向到登录页面。 如何将他重定向到“AcessDenied.aspx”页面?

9 个答案:

答案 0 :(得分:42)

[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");
        }
    }
}

答案 1 :(得分:25)

这是我的解决方案,基于eu-ge-ne的答案。 如果用户未登录,我们会正确地将用户重定向到“登录”页面,如果用户已登录但未经授权可以查看该页面,则会将其重定向到“拒绝访问”页面。

[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();
}

观看/帐户/ Denied.cshtml :( Razor语法)

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

<h2>@ViewBag.Title</h2>

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

答案 2 :(得分:8)

tvanfosson查看Answerthis very similar question,这就是我正在做的事(感谢tvanfosson),所以现在我只想说:

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

如果用户不在角色中,他们将获得ViewName指定的视图。

答案 3 :(得分:6)

通过避免对Logon页面进行硬编码以及在属性中选择设置拒绝访问视图的需要,对Matt的答案略有改进:

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);
        }
    }
}

答案 4 :(得分:6)

重定向并不总是最佳解决方案

使用标准的http代码403:

return new HttpStatusCodeResult(HttpStatusCode.Forbidden);

答案 5 :(得分:1)

我有类似的问题。无论我担任什么角色,我总是被重定向到LogIn页面而不是AccessDenied。 该修复程序非常简单,但可能并非在所有情况下都有效。原来,我在这两行的Startup.cs中的顺序错误:

app.UseAuthentication();
app.UseAuthorization();

确保是否app.UseAuthentication();是之前应用。UseAuthorization();

换句话说,问“你是谁?”首先,然后是“您允许在这里吗?”,而不是相反。

答案 6 :(得分:0)

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 :(得分:0)

我建立了Vic的回答,允许我为每个应用程序的区域设置一个不同的Access Denied页面。是通过返回RedirectToRouteResult而不是重定向到相对于应用程序根目录的URL而是重定向到当前区域的控制器和操作:

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 :(得分:0)

维克阿尔卡萨的一个小小的更新, 在重定向中添加了请求URL的详细信息 这样就可以记录被拒绝访问的详细信息以及如果想要的人

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));
        }
    }
}