我正在创建一个自定义角色提供程序,并设置了一个Authorize属性,在我的控制器中指定了一个角色,它的工作正常,如下所示:
[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...
但是当用户无法访问此控制器时,他会被重定向到登录页面。 如何将他重定向到“AcessDenied.aspx”页面?
答案 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查看Answer的this 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));
}
}
}