Asp.net MVC5和WebApi2在控制器上具有Authorize
属性,可让您过滤角色。例如:
[Authorize(Roles="HomePageUser")]
public ActionResult Home(){
return View();
}
但是,如果用户经过身份验证但没有正确的角色,则会发出401
状态代码。我的问题很简单:这是最好的方法,还是应该编写一个过滤器,如果它们经过身份验证但发送错误,则发送403
?
要了解这是一个问题,请考虑:不在角色HomePageUser
的用户登录并尝试转到Home
页面。 Authorize
过滤器发出401代码,然后Owin上下文拦截并转换为302重定向到登录页面。但是,用户实际上已登录,并且没有多少登录可以纠正用户的身份缺乏查看页面的权限这一事实。
实际上,这一切都意味着用户感到沮丧,因为自动重定向从不向他们提供有关他们为什么无法看到该页面的任何信息 - 他们可能会认为他们输入的密码不正确。
在我看来,这里的关键失败是Authorize
过滤器撒谎 - 用户未被授权但被禁止,并且应该发出403.
这是我想要解决此问题的代码。对于MVC操作:
using System.Web.Mvc;
public class AuthorizeOrForbidAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new HttpStatusCodeResult(403);
}
else
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
以及Web Api操作:
using System.Web.Http;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Security.Principal;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Http.Properties;
public class AuthorizeOrForbidAttribute: AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (actionContext.RequestContext.Principal.Identity.IsAuthenticated)
{
actionContext.Response = actionContext.ControllerContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, actionContext.RequestContext.Principal.Identity.Name+" does not have permissions for this request.");
}
else
{
actionContext.Response = actionContext.ControllerContext.Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Authorization has been denied for this request.");
}
}
}
从那里可以很容易地将这些状态代码重定向到相应的错误页面,具体取决于您希望用户看到的内容。
这是一个好方法吗?我很担心,因为我想知道微软是不是一开始就没有这么做的好理由。
答案 0 :(得分:0)
但是,用户实际上已登录,并且没有多少登录可以纠正用户身份缺乏查看页面权限这一事实。
如果他们无法使用允许他们访问相关资源的帐户登录,那么他们为什么要去那里?
要么他们故意试图做一些不应该工作的事情,在这种情况下我不会对他们的挫折感到那么多的同情,或者有链接或其他导航功能表明他们可以做到这一点,这是一个更大的问题,无论如何都会导致挫败感。
除此之外,这两种方法都有其支持者。禁止方法的优点是能够引导用户做他们能做的事情。登录提示的好处是能够使用其他帐户登录,如果资源是您可以访问的资源,则继续。
如果您在禁止错误页面上包含登录表单,则可以拥有两者的功能,以涵盖该案例。