我正在创建一个自定义角色提供程序,并在我的控制器中设置了一个指定角色的 Authorize 属性,它工作得很好,如下所示:
[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...
但是当用户无权访问这个控制器时,他会被重定向到登录页面。如何将他重定向到“AcessDenied.aspx”页面?
我正在创建一个自定义角色提供程序,并在我的控制器中设置了一个指定角色的 Authorize 属性,它工作得很好,如下所示:
[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...
但是当用户无权访问这个控制器时,他会被重定向到登录页面。如何将他重定向到“AcessDenied.aspx”页面?
[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");
}
}
}
这是我的解决方案,基于 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();
}
Views/Account/Denied.cshtml:(Razor 语法)
@{
ViewBag.Title = "Access Denied";
}
<h2>@ViewBag.Title</h2>
Sorry, but you don't have access to that page.
从这个非常相似的问题中查看tvanfosson的答案,这就是我正在做的事情(感谢 tvanfosson),所以现在我只需要说:
[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")]
public class SuperAdminController : Controller
...
如果用户不在角色中,他们将获得 ViewName 指定的视图。
重定向并不总是最好的解决方案
使用标准 http 代码 403:
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
通过避免对登录页面进行硬编码并可选地在属性中设置访问被拒绝视图,对马特的回答略有改进:
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);
}
}
}
我有类似的问题。无论我担任什么角色,我总是被重定向到登录页面而不是 AccessDenied。修复非常简单,但可能并非在所有情况下都有效。事实证明,我在 Startup.cs 中这两行的顺序错误:
app.UseAuthentication();
app.UseAuthorization();
确保 app.UseAuthentication(); 在app.UseAuthorization () 之前;
换句话说,问“你是谁?” 首先,然后是“你可以在这里吗?”,而不是相反。
只是对 Vic Alcazar 的一个小更新,在重定向中添加了请求 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));
}
}
}
我以 Vic 的回答为基础,允许我为每个应用程序区域提供不同的拒绝访问页面。通过返回 aRedirectToRouteResult
而不是重定向到相对于应用程序根目录的 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 }));
}
}
}
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");
}
}
}